目录
主要内容:
1. QT定时器事件
2. Mat采集数据,读取一帧数据
3. opencv的Mat格式数据(BGR)转换为QT的QImage(RGB)
4. 显示图像
#include "faceattendence.h"
#include "ui_faceattendence.h"
#include <QImage>
#include <QPainter>
#include <QDebug>
FaceAttendence::FaceAttendence(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::FaceAttendence)
{
ui->setupUi(this);
// 打开摄像头
cap.open(0); //linux 改为 dev/video
// 启动定时器事件
startTimer(100);
}
FaceAttendence::~FaceAttendence()
{
delete ui;
}
void FaceAttendence::timerEvent(QTimerEvent *e)
{
// 采集数据
Mat SrcImage;
if(cap.grab()){
cap.read(SrcImage);// 读取一帧数据
}
//读取不到摄像头数据,返回
if(SrcImage.data == nullptr) return;
//把opencv的Mat格式数据(BGR)转换为QT的QImage(RGB)
cvtColor(SrcImage, SrcImage, COLOR_BGR2RGB);
QImage image(SrcImage.data, SrcImage.cols, SrcImage.rows, SrcImage.step1(), QImage::Format_RGB888);
QPixmap mmp = QPixmap::fromImage(image);
ui->videoLb->setPixmap(mmp);
}
1 QT定时器事件
启动定时器事件是为了定期执行某些操作。在代码中,定时器事件被用来定期从摄像头捕获一帧图像并在界面上显示。具体来说,每隔一段时间(每 100 毫秒),Qt 会自动调用
timerEvent
函数,在这个函数中从摄像头获取图像并将其显示在界面上。通过这种方式,应用程序能够定期更新摄像头的图像显示,这样就实现了视频流的实时显示效果。每次定时器事件触发时,都会执行
timerEvent
函数中的代码,从而刷新显示在QLabel
(如videoLb
)上的图像
参考博文
1.1 主要对象
QT框架中提供了两种类型的定时器:QTimer和QTimerEvent。
1.QTimer:QTimer是QT提供的一个高级定时器类,它基于QObject类,并且可以与事件循环一起工作。QTimer提供了灵活的定时器功能,可以执行单次或周期性的定时任务。
QTimer *timer = new QTimer(this);
// 设置定时器间隔时间
timer->setInterval(1000); // 每隔1秒触发一次定时器事件
// 连接定时器事件和槽函数
// 定时器到期后,自动发送timeout信号
connect(timer, &QTimer::timeout, this, &MyClass::handleTimerEvent);
// 启动定时器
timer->start();
2.QTimerEvent:QTimerEvent是QT中的一个事件类,它用于处理与QTimer相关的事件。在继承了QObject的类中,可以重写QObject的虚函数timerEvent(QTimerEvent* event)
来处理定时器事件。
void MyClass::timerEvent(QTimerEvent *event)
{
if (event->timerId() == timerId) {
// 处理定时器事件的逻辑
}
QObject::timerEvent(event);
}
QTimer是较为常用和方便的定时器类,它提供了简单的接口和信号槽机制来处理定时器事件。QTimerEvent则更加底层,需要手动重写timerEvent函数,并进行定时器事件的处理逻辑。
1.2 QTTimer定时的特点
简单易用:QT定时器提供了简洁、易于使用的接口,使开发人员可以轻松创建和管理定时器对象。
灵活性:QT定时器支持各种类型的定时器,包括单次定时器、重复定时器和单次重叠定时器,可以根据具体需求选择合适的类型。
高精度:QT定时器能够提供高精度的计时能力,通常以毫秒级别为单位。这样,开发人员可以实现精确的定时任务,满足应用程序的需求。QT定时器的最小精度是毫秒。
线程安全:QT定时器可以安全地在多线程环境中使用。它提供了线程安全的机制,使定时器能够在不同线程中创建、启动和停止,以满足多线程应用程序的需求。
与信号槽机制集成:QT定时器可以与QT的信号槽机制无缝集成。开发人员可以将定时器的超时信号(timeout)与其他对象的槽函数或lambda表达式连接,实现灵活的定时任务逻辑。
多平台支持:QT定时器在不同平台的行为表现一致,无论是在Windows、MacOS、Linux等操作系统上,还是在嵌入式系统上。这保证了代码在不同平台下的可移植性和一致性。
高度集成:QT定时器可以与QT框架中的其他组件高度集成,如GUI控件、网络功能等。这使得开发人员可以将定时器与其他功能相结合,实现丰富的交互和功能。
2 Mat类
参考博文
http://t.csdnimg.cn/iNCmt
2.1 Mat的基本结构
Mat 是一个包含两个数据部分的类:矩阵头(matrix header),包含矩阵大小、存储方法、存储矩阵的地址等信息和指向矩阵的指针(pointer),矩阵包含像素值。矩阵头部的大小是固定的,但矩阵本身的大小可能会因图像大小而异。
每个 Mat 对象都有自己的头,但是一个矩阵可以在两个 Mat 对象之间通过让它们的【矩阵指针】指向相同的地址来共享。此外,复制操作符只复制大矩阵的矩阵头和指针,而不复制图像数据本身。
2.1.1 浅拷贝
Mat A, C; // 仅仅创建矩阵头(matrix header)
A = imread(argv[1], IMREAD_COLOR); // 分配内存,存储图像数据
Mat B(A); // 使用复制构造器(copy constructor)
C = A; // 赋值操作符(Assignment operator)
上述所有对象(B,C)都指向同一个数据矩阵,对其中任何一个进行修改都会影响其它所有对象。
2.1.2 深拷贝
如果不希望原始图像被修改,可以使用深拷贝的方法
Mat F = A.clone();
Mat G;
A.copyTo(G);
2.2 颜色表示方法
关于如何存储像素值的:
我们可以选择颜色空间(color space)和所使用的数据类型(data type)。颜色空间是指如何组合颜色组件来编码给定的颜色。
2.3 Mat类常用成员函数
Mat (int rows,int cols, int type)
Mat (Size size, int type)
3 QImage与QPixmap
参考博文
3.1 数据结构和用途
- QImage: QImage 是一个更底层的图像类,它包含了图像的像素数据、颜色信息、以及图像的格式等。QImage 可以用于图像处理、像素级别的操作、格式转换等。QImage 是一个灵活的图像处理类,可以直接从文件、内存、设备等加载图像数据。
- QPixmap: QPixmap 是一个基于设备的图像表示,它通常用于在界面上显示图像、图标、背景等。QPixmap 隐藏了图像的底层数据结构,提供了方便的界面显示接口。QPixmap 可以用于在窗口、控件等上绘制图像,以及进行界面元素的图像显示。
3.2 适用场景
- QImage: 适用于需要对图像进行复杂处理、像素级别的操作、格式转换等情况。如果你需要在图像上进行算法操作、图像分析、修改像素值等,通常使用 QImage 更为合适。
- QPixmap: 适用于在界面上显示图像、图标、背景等情况。如果你需要在界面元素(例如窗口、按钮、标签等)上显示图像,通常使用 QPixmap 更为方便。QPixmap 是更高级、更用户友好的图像显示类。
3.3 性能和优化
- QImage: 由于包含了详细的图像数据,QImage 的内存占用较大。在处理大量图像数据时,可能会占用较多的内存。同时,QImage 的像素级别操作可能较为耗时,特别是在大尺寸图像上。
- QPixmap: QPixmap 是一个较为轻量级的图像表示,它通常会被优化以适应界面的显示需求。在绘制图像到界面上时,QPixmap 的性能较好,因为它通常会利用硬件加速等技术来提高绘制效率。
4 VideoCapture类
4.1 摄像头操作
OpenCV不仅能够处理图像,还能够处理视频
视频是由大量的图像构成的,这些图像是以固定的时间间隔从视频中获取的。这样,就能够使用图像处理的方法对这些图像进行处理,进而达到处理视频的目的。要想处理视频,需要先对视频进行读取、显示、保存等相关操作。为此,OpenCV提供了VideoCapture类和 VideoWiter 类的相关方法
为了读取并显示摄像头视频,OpenCV 提供了 VideoCapture 类的相关方法,这些方法包括摄像头的初始化方法、检验摄像头初始化是否成功的方法、从摄像头中读取帧的方法、关闭摄像头的方法等。
Tips :视频是由大量图像构成,这些图像称为帧
4.2 相关函数
4.2.1 cap.open()、cap()
打开摄像头
- index = 0 :表示打开第一个摄像头,对于64位笔记本,打开的就是内置摄像头
- index = 1 :表示打开第二个摄像头,对于64位笔记本,打开的就是连接笔记本的外置摄像头
4.2.2 isOpened()
检测初始化是否成功
4.2.3 grab()
抓取视频一帧但不解码
4.2.4 read()
读取并解码视频一帧
4.2.5 release()
释放视频捕获设备