我使用OpenCV和Qt Libraries以及VS 2010在Win7 x64上工作 .
我想用OpenCV打开我的相机然后用Qt显示捕获的帧,例如使用QLabel,从Mat转换为QImage .
我想这样做是因为使用函数imshow(“camera”,image)和waitKey()减慢了流式摄像机的速度 .
这是我的代码:
int main () {
QApplication a(argc, argv);
QLabel myLabel;
VideoCapture cap(0);
//namedWindow(c"camera", 1);
for (;;) {
cap >> image;
//conversion from Mat to QImage
Mat dest;
cvtColor(image, dest,CV_BGR2RGB);
QImage image1= QImage((uchar*) dest.data, dest.cols, dest.rows, dest.step, QImage::Format_RGB888);
//show Qimage using QLabel
myLabel.setPixmap(QPixmap::fromImage(image1));
myLabel.show();
//imshow("camera",image);
//if (waitKey(30)>= 0) break;
}
return a.exec();
}
网络摄像头打开正常并且可以工作,但是我看到一个白色的窗口,而不是捕获的帧,正如您在此图像中看到的那样
如果我取消注释: namedWindow (..), imshow(..), if(waitKey(..)
,它可以工作(我看到两个窗口具有相同的图像),但我用OpenCV显示捕获的帧,这是我想要避免的 .
我的问题是:我错了什么?我不知道,从Mat到Qimage的转换是错误的??或者,我不能只用Qt显示捕获的帧?
谢谢!
3 回答
我没有太多经验,但我可以看到这里可能出现的问题:
你是在死循环中这样做 - 这将导致你的QLabel无限更新自己,所以你可能看不到任何东西 . 此外,如果取消注释
waitKey
正在帮助您,那么这几乎意味着您正在将数据转换为QImage
,但其他内容已被破坏 .请注意
a.exec()
将永远不会执行,因为您将陷入循环,但我想这足以击中概念 .为了不阻塞事件循环,您需要创建
QTimer
并每隔x毫秒更新一次窗口小部件:在要用于显示图像的窗口小部件(窗口小部件/主窗口)的
paintEvent()
中尝试此操作 .在窗口小部件的构造函数中打开相机:
在
paintEvent()
这样做使用计时器,您可以将
timeout
SIGNAL连接到窗口小部件的update
SLOT . 使用20-40毫秒的间隔 . 就像你按下按钮启动相机一样,将以下代码放在clicked
SLOT中 .如果你设置在Label中开始捕获视频,那么你必须在CPP中编写这样的代码:这段代码对我来说非常好,我希望它也能帮到你 .
在 Headers 中: