簡體   English   中英

在帶有 Qt 的 Linux Ubuntu 平台上使用 OpenCV 2.2 顯示圖像

[英]Showing an image using OpenCV 2.2 on a Linux Ubuntu platform with Qt

我在 Ubuntu 10.10 和 OpenCV 2.2 上使用Qt作為我的 C++ IDE 平台。

我將只編寫代碼段並顯示問題所在:

#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命令無法打開新窗口。

你的假設是不正確的。 OpenCV 將擁有自己的 X 服務器連接,並且不受 Qt 窗口管理的影響(但是,waitKey() 輸入處理和 app.exec() 不會並行工作)。

我還測試了類似的代碼以發現任何不可預見的副作用。 在我的帶有 OpenCV 2.2 和 Qt 4.6.2 的 Debian 機器上,所有窗口都可以正常繪制。

對你來說一個簡單的測試可能是在你的 while 循環之后創建 app 對象。 但是,可能只是堆棧布局中的隨機變化導致您的警告成為嚴重問題? 您還應該檢查 valgrind。

我最近遇到了類似的問題(使用 OpenCV 和 Qt 作為最終 GUI 顯示網絡攝像頭信息)。 我發現播放視頻(基本上是一組圖像)的最佳方法是使用 GLWidget。 在這個 GLWidget 中,您可以創建一個矩形並為其附加紋理,其中紋理是您要顯示的圖像。 另一個問題是 OpenCV 和 OpenGL 的圖像格式不同,但是您可以通過更改通道的順序輕松更改格式。

在您的代碼中,您正在創建一個 QApplication ,它具有自己的中間進程,因此您永遠不會到達您的 while 循環。 您還沒有創建任何 Qt 顯示窗口,我建議您查看 Qt 附帶的示例以檢查應用程序的基本結構,並從 QMainWindow 或 QDialog 開始。

步驟是:

  1. 創建您的主窗口(我使用的是QDialog )。
  2. 創建一個GLWidget並將其添加到 Dialog/MainWindow 的布局中。
  3. 從 OpenCV 接收圖像並將其轉換為 OpenGL 正確顯示的格式。
  4. 使用 OpenGL,創建一個矩形並將圖像附加為紋理

你的問題是 Qt 處理它自己的事件循環,因此 OpenCV 的事件循環是飢餓的,永遠不會運行。

讓它們一起工作的方法非常簡單:將您的 OpenCV 顯示為 QPixmap(通過將您的圖像轉換為 QImage,然后使用 QLabel 來顯示它)。 然后將此 QLabel 添加到您的 QWidget。 您的 QWidget 可以被嵌入或成為您的 QApplication 的主要小部件。

要將 cv::Mat 圖像的緩沖區用作 QImage,請參閱此答案如何將 opencv cv::Mat 轉換為 qimage

要顯示此 QImage,請參閱使用 QtGui 顯示 QImage

你不能混合 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());

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM