multithreaded Qt+OpenCV
multithreaded Qt+OpenCV
我将使用OpenCV和MAT类型制作一个线程,该线程从网络摄像头相机中收回图像。然后,我将其转换为qimage,并使用信号将其发送到主线程。当我想在UI中的Qlabel对象中可视化它(转换为PixMap之后)时,我会得到此错误:
该程序意外完成。
这是我的相机课:相机。H:
#ifndef CAMERA_H
#define CAMERA_H
#include <QObject>
#include <QThread>
#include <QtCore>
#include <QtGui>
#include <opencv2/opencv.hpp>
using namespace cv;
class Camera: public QThread
{
Q_OBJECT
public:
Camera();
void run();
bool Stop = false;
signals:
void ImgSignal(QImage*);
private:
public slots:
};
#endif // THREAD_H
camera.cpp:
#include "camera.h"
#include <iostream>
using namespace std;
Camera::Camera()
{
}
void Camera::run()
{
VideoCapture cap;
cap.open(0);
while(1){
Mat img;
cap >> img;
cvtColor(img,img,CV_BGR2RGB);
QImage image = QImage((const uchar*)img.data,img.cols,img.rows,img.step,QImage::Format_RGB888);
emit ImgSignal(&image);
QThread::msleep(30);
}
}
最后,我的onimgsignal功能将图像收回并将其传递给GUI:
void MainWindow::onImgSignal(QImage *img)
{
QPixmap *p;
p->fromImage(*img);
ui->label->setPixmap(*p);
}
如果您帮助我,我会很高兴。谢谢!
编辑当我将PixMap Poiner更改为PixMap变量时,错误不会出现,但是PixMap变量为null。即使我单独加载图像也将是零的:
QPixmap p;
p.load("mark.png");
cout << p.isNull();
ui->label->setPixmap(p);
我的第一个预感是,某些指向某些对象/内存的指针同时被两个不同的线程偶然访问,从而违反了访问权限。因此,通过仅制作您传递的图像的副本,可能会解决这个问题(因此,这两个线程AR都无法同时访问同一图像的像素数据)。您可以做其他一些事情来解决:
首先,QT中的线程实现有点非常规。例如,像您所做的那样扩展QThread
类的最佳实践并不是最佳实践,因为QThread
实例将不是现场直播在新的OS级线程中。是的!这是真的。这导致了许多混乱来源,进而导致错误。要阅读有关如何在QT中正确执行线程的官方非官方指南,请查看这篇出色的文章。简短摘要:QThread
类将充当居住在您实例化的执行线程中的"管理"类,因此第一个提示是学习此内容,并按照预期使用QThread
类。
第二,QT应该在信号时间内猜测源和目的地是否处于相同的线程,但是我发现有时候,仅出于心灵的安心,付费是具体说明如何通过信号。这就是为什么我的代码充满此的原因:
if(!connect(this,SIGNAL(colorChanged(QColor)),&ob,SLOT(onColorChanged(QColor)),(Qt::ConnectionType) (Qt::QueuedConnection | Qt::UniqueConnection) )) {
qWarning()<<"ERROR: Could not connect "<<ob.objectName();
}
请注意连接调用的最后一个参数,因为它指定了Qt::QueuedConnection
和Qt::UniqueConnection
连接。Qt::QueuedConnection
意味着它是"线程安全",因为它将信号存储在螺纹安全的FIFO中。Qt::UniqueConnection
只是意味着连接两次将第二次生成错误,而不是创建两个连接(这可能导致难以跟踪的错误)。
第三,您是否在不使用QT的情况下启动任何线程?在这种情况下,应使用信号进行护理,因为除非您使用QT启动线程,否则它们可能无法正常工作。我认为上面的Qt::QueuedConnection
技巧应该足够了,但我不知道。这是更多。哦,如果OpenCV曾经有意或在不知不觉地启动其自己的某些线程,那么他们将算作"线程在qt之外启动" 。
第四,您是否在调试器中运行此操作?在什么确切的时候崩溃了?这应该是您的第一步,顺便说一句。
第五,如果其他所有因素都未能将代码包裹在QMutex
中,并使用QMutexLocker
确保没有问题。或者,您可能会很花哨,并使用一些线程安全的容器或类似的线程。
PS:请让我知道您的票价!
- 如果不在窗口 10 中声明名为 openCV 的 openCV namedWindow,QT 图像显示将无法正常工作
- OpenCV QT,显示视频的帧(不使用while循环)
- 在从Qt调用的Python脚本中导入OpenCV崩溃
- 如何使用opencv和Qt拍摄部分桌面的照片
- 为arm64-v8a编译Qt和OpenCV
- 如何以及在何处使用带QT的Basler Cam实现opencv人脸检测代码
- 通过QT WebSocket将OpenCV Mat Image发送到HTML客户端
- 如何使用Opencv,qt creator,ming gw窗口在一起
- 带有QT OpenCV的多线程
- QT opencv msvc2015 x64
- multithreaded Qt+OpenCV
- QT OpenCV setMouseCallback "argument type does not match"
- 在Qt+Opencv中导入Gstreamer视频
- qt opencv -sigsegv显示转换的帧
- Ubuntu 上的 Qt+OpenCV 无法运行/调试:无法启动应用程序
- Qt + OpenCV 灰度误差
- Qt + OpenCV in Debian
- Qt OpenCV网络摄像头流打开和关闭
- 使用 Qt + Opencv 时未定义的 Opencv 引用
- Qt + OpenCV + Mac OS -> Can't fid libpng