当前位置: 首页 > news >正文

QT opencv(显示图片和视频)

文章目录

  • 前言
  • 一、使用opencv显示图片
  • 二、QT opencv播放视频
      • `VideoCapture` 的基本用法
        • 1. **创建 `VideoCapture` 对象**
        • 2. **检查是否成功打开**
        • 3. **读取视频帧**
        • 4. **释放资源**
      • `VideoCapture` 的常用方法
      • 常见用途
      • `VideoCapture` 打开失败的原因
  • 三、QT opencv打开摄像头


前言

本篇文章将带大家来学习使用opencv在QT中显示图片和视频等基础功能。

一、使用opencv显示图片

cv::Mat 类
cv::Mat 是 OpenCV 中用来表示图像的基本数据结构。它是一个矩阵类,可以存储图像数据、以及图像的相关信息。

主要特点
矩阵结构:cv::Mat 是一个通用的矩阵类,可以用于存储图像、特征点、深度图等数据。

数据存储:图像数据通常以矩阵的形式存储,每个像素的值可以是单通道(灰度图像)或多通道(彩色图像)。

内存管理:cv::Mat 提供了自动内存管理功能,当不再需要时会自动释放内存。

访问数据:可以通过指针、索引或迭代器来访问矩阵中的数据。

构造函数和成员函数
构造函数:cv::Mat 可以通过多种构造函数创建,如指定尺寸和数据类型的空矩阵、从图像文件加载等。

数据访问:
at<>():访问矩阵中特定位置的像素值。

data:获取矩阵数据的指针。

cv::imread 函数
cv::imread 是 OpenCV 中用来从文件读取图像并将其加载到 cv::Mat 对象中的函数。

主要参数
filename:要读取的图像文件的路径。

flags:读取图像的标志,决定图像的读取模式。

cv::IMREAD_COLOR(默认):以彩色图像的形式读取,忽略图像的透明度。
cv::IMREAD_GRAYSCALE:以灰度图像的形式读取。
cv::IMREAD_UNCHANGED:读取图像时包括图像的 alpha 通道(透明度)。

widget.cpp:

#include "widget.h"
#include "ui_widget.h"
#include <QImage>
#include <QPixmap>
#include <opencv2/opencv.hpp>// 将 OpenCV 的 Mat 转换为 Qt 的 QImage
QImage matToQImage(const cv::Mat& mat)
{switch (mat.type()){case CV_8UC1:return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8);case CV_8UC3:return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888).rgbSwapped();default:qWarning("Unsupported image format");return QImage();}
}Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 创建 QLabel 和 QPushButton 实例button1 = new QPushButton("Button", this); // 创建并设置按钮的文本label.setFixedSize(640, 480); // 设置 label 的固定大小// 创建水平布局并将控件添加到布局中Hlayout = new QHBoxLayout(this);Hlayout->addWidget(&label); // 将 QLabel 添加到布局中Hlayout->addWidget(button1); // 将 QPushButton 添加到布局中setLayout(Hlayout); // 将布局设置为 Widget 的布局cv::Mat image = cv::imread("H:/QT opencv/code/myopencv/icon/1.jpg"); // 读取图像// 将 OpenCV 的 Mat 转换为 Qt 的 QImageQImage qImage = matToQImage(image);// 显示图像label.setPixmap(QPixmap::fromImage(qImage));
}Widget::~Widget()
{delete ui;
}

widget.h:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QLabel>
#include <QHBoxLayout>
#include <QPushButton>QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTQLabel label;QHBoxLayout* Hlayout;QPushButton* button1;public:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;
};
#endif // WIDGET_H

代码思路总结
组件创建:在构造函数中,创建了 QPushButton 和 QLabel 实例,并设置了图像显示和按钮的文本。

布局管理:使用 QHBoxLayout 布局管理器将 QLabel 和 QPushButton 添加到布局中,确保它们在窗口中水平排列。

图像处理:读取图像文件,使用 matToQImage 函数将 OpenCV 的 Mat 对象转换为 Qt 的 QImage 对象,并设置为 QLabel 的显示内容。

显示效果:

在这里插入图片描述

二、QT opencv播放视频

VideoCapture 是 OpenCV 库中用于视频捕获和读取的类。它能够从视频文件、摄像头或其他视频流中捕获帧,并将其作为图像进行处理和显示。以下是关于 VideoCapture 的详细讲解。

VideoCapture 的基本用法

1. 创建 VideoCapture 对象
  • 从摄像头捕获:

    cv::VideoCapture cap(0); // 打开默认摄像头
    
    • 参数 0 表示打开默认摄像头。如果有多个摄像头,可以使用 12 等来指定。
  • 从视频文件读取:

    cv::VideoCapture cap("video.mp4"); // 打开视频文件
    
    • 参数是视频文件的路径。
2. 检查是否成功打开
  • 成功打开摄像头或视频文件后,应该检查是否成功打开:
    if (!cap.isOpened()) {std::cerr << "Error: Could not open video file or camera" << std::endl;return -1;
    }
    
    • cap.isOpened() 返回 true 表示成功打开,返回 false 表示打开失败。
3. 读取视频帧
  • 逐帧读取:
    cv::Mat frame;
    while (cap.read(frame)) {// 在这里处理帧,例如显示它cv::imshow("Frame", frame);// 等待 30 毫秒并检查是否按下了退出键if (cv::waitKey(30) >= 0) {break;}
    }
    
    • cap.read(frame) 读取一帧并存储到 frame 中。读取成功返回 true,否则返回 false
    • cv::imshow("Frame", frame) 显示当前帧。
    • cv::waitKey(30) 等待 30 毫秒,并检测是否按下键盘。如果按下键(例如 Esc),可以退出循环。
4. 释放资源
  • 当捕获或读取操作完成后,应释放资源:
    cap.release();
    cv::destroyAllWindows();
    

VideoCapture 的常用方法

  • bool open(int device): 打开摄像头设备,参数为设备索引。
  • bool open(const std::string &filename): 打开视频文件,参数为文件路径。
  • bool isOpened(): 检查视频源是否成功打开。
  • bool read(cv::Mat &image): 读取当前帧并存储在 image 中。
  • void release(): 释放视频捕获设备或文件。
  • double get(int propId): 获取视频属性,例如帧宽、高、帧率等。
    • 例如,cap.get(cv::CAP_PROP_FRAME_WIDTH) 返回帧的宽度。
  • bool set(int propId, double value): 设置视频属性,例如帧宽、高、帧率等。

常见用途

  1. 摄像头实时捕获:通过 VideoCapture 可以捕获摄像头实时视频流,并进行处理、显示或保存。

  2. 视频文件读取和处理:可以读取本地或远程的视频文件,逐帧处理,如视频剪辑、帧插值、目标跟踪等。

  3. 视频属性获取和设置:可以获取和设置视频流的属性,如帧率、分辨率、亮度、对比度等。

VideoCapture 打开失败的原因

  1. 视频文件路径错误:检查视频文件路径是否正确,文件是否存在。
  2. 文件格式不支持:确保 OpenCV 支持所使用的视频文件格式。
  3. 缺少解码器:在某些系统上,缺少必要的视频解码器,尤其是对于某些编码格式如 H.264。
  4. 摄像头被占用:检查摄像头是否被其他程序占用,或者硬件是否有问题。

widget.cpp:

#include "widget.h"
#include "ui_widget.h"
#include <QImage>
#include <QPixmap>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), videoLabel(new QLabel(this)), timer(new QTimer(this))
{ui->setupUi(this);// 设置 videoLabel 的尺寸videoLabel->setFixedSize(1000, 1000);// 创建定时器并连接到槽函数connect(timer, &QTimer::timeout, this, &Widget::updateFrame);// 打开视频文件cap.open("H:/QT opencv/code/Test/1.mp4");if (!cap.isOpened()) {qWarning("Error: Could not open video file.");return;}// 启动定时器,每30毫秒更新一次视频帧timer->start(30);
}Widget::~Widget()
{cap.release();delete ui;
}QImage Widget::matToQImage(const cv::Mat& mat)
{switch (mat.type()){case CV_8UC1:return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8);case CV_8UC3:return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888).rgbSwapped();default:qWarning("Unsupported image format");return QImage();}
}void Widget::updateFrame()
{cv::Mat frame;if (cap.read(frame)) {// 将 OpenCV 的 Mat 转换为 Qt 的 QImageQImage qImage = matToQImage(frame);// 更新 videoLabel 显示videoLabel->setPixmap(QPixmap::fromImage(qImage));}
}

widget.h:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QLabel>
#include <QTimer>
#include <opencv2/opencv.hpp>QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void updateFrame(); // 更新视频帧的槽函数private:Ui::Widget *ui;QLabel *videoLabel; // 显示视频的标签QTimer *timer; // 定时器用于刷新视频帧cv::VideoCapture cap; // OpenCV 视频捕获对象QImage matToQImage(const cv::Mat& mat); // 将 cv::Mat 转换为 QImage
};#endif // WIDGET_H

运行效果:

在这里插入图片描述

三、QT opencv打开摄像头

widget.cpp:

#include "widget.h"
#include "ui_widget.h"
#include <QImage>
#include <QPixmap>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), cap(1) // 打开摄像头
{ui->setupUi(this);cameraLabel = new QLabel(this); // 用于显示摄像头画面的 QLabelcameraLabel->setFixedSize(640, 480); // 设置显示区域的大小if (!cap.isOpened()) {qWarning("Error: Could not open camera");return;}timer = new QTimer(this);connect(timer, &QTimer::timeout, this, &Widget::updateFrame);timer->start(30); // 每 30 毫秒更新一次画面
}Widget::~Widget()
{cap.release(); // 释放摄像头delete ui;
}void Widget::updateFrame()
{cv::Mat frame;cap >> frame; // 读取摄像头当前帧if (frame.empty()) {return;}QImage qImage = matToQImage(frame); // 将 OpenCV 的 Mat 转换为 QImagecameraLabel->setPixmap(QPixmap::fromImage(qImage)); // 显示图像
}QImage Widget::matToQImage(const cv::Mat &mat)
{switch (mat.type()) {case CV_8UC1:return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8);case CV_8UC3:return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888).rgbSwapped();default:qWarning("Unsupported image format");return QImage();}
}

widget.h:

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QLabel>
#include <QTimer>
#include <opencv2/opencv.hpp>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void updateFrame();private:Ui::Widget *ui;QLabel *cameraLabel;QTimer *timer;cv::VideoCapture cap;QImage matToQImage(const cv::Mat& mat);
};#endif // WIDGET_H

运行效果:
在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 抢单源码修正版,带教程,自动抓取订单,十几种语言可自动切换
  • [数据集][目标检测]电力场景输电线防震锤检测数据集VOC+YOLO格式2721张2类别
  • 在AES加密中,设主密钥为“2B 7E 15 16 28 AE D2 A6 AB F7 15 88 09 CF 4F 3C”,试计算迭代第1轮使用的轮密钥。
  • 合合信息文档解析Coze插件发布,PDF转Markdown功能便捷集成
  • 云计算实训32——roles基本用法、使用剧本安装nginx、使用roles实现lnmp
  • AI入门指南(四):分类问题、回归问题、监督、半监督、无监督学习是什么?
  • 【3】AT32F437 OpenHarmony轻量系统第一个程序:点灯
  • C#与其它编程语言有什么区别,以及相关优势有哪些
  • Java 事务管理:确保数据一致性
  • FPGA开发——DS18B20读取温度并且在数码管上显示
  • 【达梦数据库】锁超时的处理方法-错误码[-6407]
  • 微软edge浏览器开发工具全解析
  • MYSQL -NATURAL JOIN ,exist 函数
  • LeetCode 热题100-69 有效的括号
  • 设计模式-结构性模式-桥接模式
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • Centos6.8 使用rpm安装mysql5.7
  • CSS魔法堂:Absolute Positioning就这个样
  • Fabric架构演变之路
  • input的行数自动增减
  • Java 内存分配及垃圾回收机制初探
  • java第三方包学习之lombok
  • log4j2输出到kafka
  • mac修复ab及siege安装
  • Map集合、散列表、红黑树介绍
  • Meteor的表单提交:Form
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • React中的“虫洞”——Context
  • Spark RDD学习: aggregate函数
  • vue:响应原理
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 跳前端坑前,先看看这个!!
  • ###STL(标准模板库)
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • %check_box% in rails :coditions={:has_many , :through}
  • (1)无线电失控保护(二)
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (4) PIVOT 和 UPIVOT 的使用
  • (52)只出现一次的数字III
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (五)MySQL的备份及恢复
  • (一)springboot2.7.6集成activit5.23.0之集成引擎
  • (转)详解PHP处理密码的几种方式
  • (转)用.Net的File控件上传文件的解决方案
  • ./configure,make,make install的作用
  • .net core使用EPPlus设置Excel的页眉和页脚
  • .net 设置默认首页
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .Net程序帮助文档制作