在Linux Ubuntu平台上使用OpenCV 2.2显示图像Qt

问题描述:

嘿家伙, 我在使用OpenCV 2.2的Ubuntu 10.10上使用Qt作为我的C++ IDE平台。 我就写的代码,并显示块,其中的问题是:在Linux Ubuntu平台上使用OpenCV 2.2显示图像Qt

#include "opencv2/highgui/highgui.hpp" 

using namespace cv; 

int main(int argc, char *argv[]) 
{  
    VideoCapture cap = VideoCapture(0); 
    Mat frame; 
    do 
    { 
     cap >> frame; 
     imshow("frame",frame); 
    } while (waitKey(10) != 27); 
    return 0; 
} 

我得到3警告印出似乎是这样的:

VIDIOC_QUERYMENU: Invalid argument 

,一切似乎要被罚款(相机作品)。

我不得不添加了Qt的使用,并加入3行代码,它看起来像这样:

#include <QApplication> 
#include "opencv2/highgui/highgui.hpp" 

using namespace cv; 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc,argv);  
    VideoCapture cap = VideoCapture(0); 
    Mat frame; 
    do 
    { 
     cap >> frame; 
     imshow("frame",frame); 
    } while (waitKey(10) != 27); 

    return app.exec(); 
} 

我仍然得到3条警告线,但现在,“帧”窗口是灰色的,并没有显示任何内容。

这是我第一次使用Qt,所以我真的不知道它是如何工作的。我只能猜测QApplication正在控制窗口管理,导致imshow命令无法打开新窗口。

我会感谢您的帮助, THNX!

你的问题是与Qt处理自己的事件循环,因此OpenCV的事件循环饿死,永远不会运行。

让他们一起工作的方式非常简单:将OpenCV显示为QPixmap(通过将图像转换为QImage然后使用QLabel来显示它)。然后将此QLabel添加到您的QWidget。您的QWidget可以嵌入或成为QApplication的主要部件。

要使用你的简历的缓冲垫::图像作为你的QImage,看到这个答案how to convert an opencv cv::Mat to qimage

要显示此的QImage,看到 Display QImage with QtGui

你的假设是不正确的。 OpenCV将有自己的连接到X服务器,不受Qt窗口管理的影响(但是,waitKey()输入处理和app.exec()不会平行工作)。

我也测试了类似的代码,以发现任何未知的副作用。 OpenCV 2.2和Qt 4.6.2的所有窗口在我的Debian机器上都能正常工作。

你身边的一个简单测试可能是在你的while循环之后创建app对象。但是,它可能只是您的堆栈布局中的随机更改,导致您的警告成为严重问题?你还应该检查valgrind。

我最近遇到过类似的问题(使用OpenCV和Qt作为最终的GUI显示网络摄像头信息)。我发现播放视频(基本上是一组图像)的最佳方式是使用GLWidget。在这个GLWidget中,您可以创建一个矩形并为其添加纹理,其中纹理是要显示的图像。另一个问题是OpenCV和OpenGL的图像格式不同,但您可以通过更改通道的顺序轻松更改格式。

在你的代码中,你正在创建一个拥有自己的iddle进程的QApplication,所以你永远不会到达你的while循环。您还没有创建任何Qt显示窗口,我建议您检查Qt附带的示例以检查应用程序的基本结构,并从QMainWindow或QDialog开始。

的步骤是:

  1. 创建你的主窗口(QDialog是我用什么)。
  2. 创建一个GLWidget并将其添加到您的Dialog/MainWindow的布局中。
  3. 从OpenCV接收图像并将其转换为OpenGL正确显示的格式。
  4. 使用OpenGL,create a rectangle and attach the image as a texture
+1

恕我直言,使用OpenGL对于简单的imshow操作来说是不必要的复杂。 – 2011-03-02 17:11:52

+1

当然,这取决于您认为必要的因素。他编写的代码是在while循环的每次迭代中接收一个新图像。根据我的经验,只有使用OpenGL,我才能避免在视频中闪烁(这正是我认为他正在尝试显示的内容)。 – sergi 2011-03-02 17:57:37

不能混淆的事件循环的OpenCV的控制和qt的app.exec

要么使用cvNamedWindow的Qt风格,要么从openCV简单抓取图像并将它们显示在QLabel中。或者更好地继承QWidget并编写自己的QImage画家

void OpencvWidget::paintEvent(QPaintEvent*) 
{ 
    //m_win is the window size 
    QPainter p(this);       
    p.drawImage(m_win,m_image,m_image.rect()); 

}