QT opencv(显示图片和视频)
人民网>>社会·法治

QT opencv(显示图片和视频)

2025-06-24 12:14:14 | 来源:人民网
小字号

文章目录

  • 前言
  • 一、使用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#include#include// 将 OpenCV 的 Mat 转换为 Qt 的 QImageQImage matToQImage(constcv::Mat&mat){ switch(mat.type()){ caseCV_8UC1:returnQImage(mat.data,mat.cols,mat.rows,mat.step,QImage::Format_Grayscale8);caseCV_8UC3:returnQImage(mat.data,mat.cols,mat.rows,mat.step,QImage::Format_RGB888).rgbSwapped();default:qWarning("Unsupported image format");returnQImage();}}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:

#ifndefWIDGET_H#defineWIDGET_H#include#include#include#includeQT_BEGIN_NAMESPACEnamespace Ui { class Widget;}QT_END_NAMESPACEclass Widget :public QWidget{ Q_OBJECT    QLabel 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#includeWidget::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(constcv::Mat&mat){ switch(mat.type()){ caseCV_8UC1:returnQImage(mat.data,mat.cols,mat.rows,mat.step,QImage::Format_Grayscale8);caseCV_8UC3:returnQImage(mat.data,mat.cols,mat.rows,mat.step,QImage::Format_RGB888).rgbSwapped();default:qWarning("Unsupported image format");returnQImage();}}voidWidget::updateFrame(){ cv::Mat frame;if(cap.read(frame)){ // 将 OpenCV 的 Mat 转换为 Qt 的 QImageQImage qImage =matToQImage(frame);// 更新 videoLabel 显示videoLabel->setPixmap(QPixmap::fromImage(qImage));}}

widget.h:

#ifndefWIDGET_H#defineWIDGET_H#include#include#include#includeQT_BEGIN_NAMESPACEnamespace Ui { class Widget;}QT_END_NAMESPACEclass Widget :public QWidget{ Q_OBJECTpublic:Widget(QWidget *parent =nullptr);~Widget();private slots:voidupdateFrame();// 更新视频帧的槽函数private:Ui::Widget *ui;QLabel *videoLabel;// 显示视频的标签QTimer *timer;// 定时器用于刷新视频帧cv::VideoCapture cap;// OpenCV 视频捕获对象QImage matToQImage(constcv::Mat&mat);// 将 cv::Mat 转换为 QImage};#endif// WIDGET_H

运行效果:

在这里插入图片描述

三、QT opencv打开摄像头

widget.cpp:

#include"widget.h"#include"ui_widget.h"#include#includeWidget::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;}voidWidget::updateFrame(){ cv::Mat frame;cap >>frame;// 读取摄像头当前帧if(frame.empty()){ return;}QImage qImage =matToQImage(frame);// 将 OpenCV 的 Mat 转换为 QImagecameraLabel->setPixmap(QPixmap::fromImage(qImage));// 显示图像}QImage Widget::matToQImage(constcv::Mat &mat){ switch(mat.type()){ caseCV_8UC1:returnQImage(mat.data,mat.cols,mat.rows,mat.step,QImage::Format_Grayscale8);caseCV_8UC3:returnQImage(mat.data,mat.cols,mat.rows,mat.step,QImage::Format_RGB888).rgbSwapped();default:qWarning("Unsupported image format");returnQImage();}}

widget.h:

#ifndefWIDGET_H#defineWIDGET_H#include#include#include#includeQT_BEGIN_NAMESPACEnamespace Ui { class Widget;}QT_END_NAMESPACEclass Widget :public QWidget{ Q_OBJECTpublic:Widget(QWidget *parent =nullptr);~Widget();private slots:voidupdateFrame();private:Ui::Widget *ui;QLabel *cameraLabel;QTimer *timer;cv::VideoCapture cap;QImage matToQImage(constcv::Mat&mat);};#endif// WIDGET_H

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

(责编:人民网)

分享让更多人看到