OpenCV+Qt多线程打开多摄像头

您所在的位置:网站首页 qt多窗口卡 OpenCV+Qt多线程打开多摄像头

OpenCV+Qt多线程打开多摄像头

2024-07-05 07:20| 来源: 网络整理| 查看: 265

现在网络上开源的OpenCV打开摄像头大多还是用死循环的方式,这里采用OpenCV+Qt多线程打开多个摄像头,并在一个界面上显示。本例程打开四个USB摄像头,三个型号一样,另一个型号不一样,原本想打开四个型号一样的,但是不知道为什么有一个就是打不开,现在还在查找原因。下面结合代码来讲解。

头文件thread_cam.h中定义了子线程类thread_cam,继承于QThread,功能是打开摄像头并将拍到的图片传回主线程显示,代码如下:

#ifndef THREAD_CAM_H #define THREAD_CAM_H #include #include #include "opencv2/core/core.hpp" #include "opencv2/videoio/videoio.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/imgcodecs/imgcodecs.hpp" #include "opencv2/highgui/highgui.hpp" #include #include using namespace cv; using namespace std; class thread_cam : public QThread { Q_OBJECT public: explicit thread_cam(QObject *parent = 0); thread_cam(int set_count=0)//记录打开了多少个摄像头 { count=set_count; } void show_cam(); protected: void run(); private: int count; QTimer *timer; Mat img; QImage Qimg; VideoCapture cap; signals: void return_QImage(QImage);//通过信号将子线程中采集的图片传回主线程 public slots: }; #endif // THREAD_CAM_H

widget.h里面则不用多说了,直接看代码:

#ifndef WIDGET_H #define WIDGET_H #include #include "thread_cam.h" namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked(); void get_QImage1(QImage); void get_QImage2(QImage); void get_QImage3(QImage); void get_QImage4(QImage); private: Ui::Widget *ui; thread_cam *thread_cam1; thread_cam *thread_cam2; thread_cam *thread_cam3; thread_cam *thread_cam4; QImage image; }; #endif // WIDGET_H

thread_cam.cpp里是子线程类的实现,这里讲图片作为信号参数直接传回主程序会导致速度变慢,以后再想办法改进。

#include "thread_cam.h" #include thread_cam::thread_cam(QObject *parent) : QThread(parent) { } void thread_cam::run() { cap=VideoCapture(count); QString massage=QString("camera%1 opens fail").arg(count); if(!cap.isOpened()) { qDebug()exec();//此句必须有,否则线程会立即结束 } void thread_cam::show_cam() { cap>>img; cvtColor(img,img,CV_BGR2RGB);//opencv中的图片以BGR格式保存,Qt中是RGB,故先转换格式再将Mat转为QImage QImage Qimg((uchar*) img.data, img.cols, img.rows, img.step, QImage::Format_RGB888 ); QString cam_name=QString("camera%1").arg(count); //imshow(cam_name.toStdString(),img); emit return_QImage(Qimg); }

接下来就是主线程里处理的东西:

#include "widget.h" #include "ui_widget.h" #include Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); thread_cam1=new thread_cam(0); thread_cam2=new thread_cam(1); thread_cam3=new thread_cam(2); thread_cam4=new thread_cam(3); connect(thread_cam1,&thread_cam::return_QImage,this,&Widget::get_QImage1); connect(thread_cam2,&thread_cam::return_QImage,this,&Widget::get_QImage2); connect(thread_cam3,&thread_cam::return_QImage,this,&Widget::get_QImage3); connect(thread_cam4,&thread_cam::return_QImage,this,&Widget::get_QImage4); } Widget::~Widget() { delete ui; } void Widget::get_QImage1(QImage img_temp) { image=img_temp; image.scaled(ui->label->width(),ui->label->height()); ui->label->setPixmap(QPixmap::fromImage(image)); } void Widget::get_QImage2(QImage img_temp) { image=img_temp; image.scaled(ui->label_2->width(),ui->label_2->height()); ui->label_2->setPixmap(QPixmap::fromImage(image)); } void Widget::get_QImage3(QImage img_temp) { image=img_temp; image.scaled(ui->label_3->width(),ui->label_3->height()); ui->label_3->setPixmap(QPixmap::fromImage(image)); } void Widget::get_QImage4(QImage img_temp) { image=img_temp; image.scaled(ui->label_4->width(),ui->label_4->height()); ui->label_4->setPixmap(QPixmap::fromImage(image)); } void Widget::on_pushButton_clicked() { thread_cam1->start();//启动线程 thread_cam2->start(); thread_cam3->start(); thread_cam4->start(); } void Widget::on_pushButton_2_clicked() { thread_cam1->quit();//关闭线程 thread_cam2->quit(); thread_cam3->quit(); thread_cam4->quit(); }

最后看看效果:



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3