OpenCV+中把cvNamedWindow(char*,int+flag)創建的窗口+同時顯示QT性能+或+關閉掉Qt性能

 

       要把cvNamedWindow(char*,int flag)創建的窗口 顯示QT性能,如: 顯示座標、像素值、放大、pan 和save 等,

 
方法一:在編譯OpenCV庫時選中 WITH_QT。


方法二:在OpenCV常規庫建立後(也就是沒有選WITH_QT 項編譯的庫), 可以在C:\OpenCV231\opencv\modules\highgui\src原文件目錄中,
 copy 這3個文件:window_QT.cpp、window_QT.h、window_QT.qrc 和一個目錄files_Qt\ 到自己的project\ 目錄下,並且:

 1)註釋掉window_QT.h中line44,如“//#include "precomp.hpp"” ,
 並添加 include 如: #include "cxcore.h"
                                  #include "cv.h"
                                  #include "highgui.h"”


 2)註釋掉 window_QT.cpp中line43,如: //#if defined(HAVE_QT)” 和最後一行,“//#endif


 3)打開window_QT.qrc的屬性,並且在:
  Custom Build Step---->Command Line中:
   "$(QTDIR)\bin\rcc.exe"  -name window_QT -o ../GeneratedFiles/qrc_window_QT.cpp  ../window_QT.qrc
  Custom Build Step---->Discription:RCC window_QT.qrc
  Custom Build Step---->Outputs:../GeneratedFiles/qrc_window_QT.cpp
  Custom Build Step---->Additional Dependencies:"$(QTDIR)\bin\rcc.exe";"../window_QT.qrc"


 4)在把編譯的“qrc_window_QT.cpp”文件加入 項目中。

 5)再次編譯,OK!

 因爲 上面3個文件中重新用QT實現了highgui中的相關函數如cvNamedWindow(char*,int flag),在工程中包含 這上個文件,程序中call的函數就直接到這3個文件中找,而屏蔽掉了OpenCv庫中的相關函數了。


 ps:1.  也許還要再Linker---->input 中加入QtTestd4.lib
        2.  如果cvNamedWindow(char*,int flag)創立的窗口在子線程中(不在GUI線程中),則不能用 WITH_QT的OpenCV庫(i.e.方法一 、二都不行)。 這時,一個solution 就是 在子線程中用普通庫裏的 cvNamedWindow(char*,int flag),而在gui線程中用 帶有 WITH_QT庫 之中的cvNamedWindow_1(char*,int flag)(由cvNamedWindow()改名 ),即實現 在程序中用 兩種類型window。


方法三:實現 在程序中同時用 兩種類型window。也就是在方法二的基礎上把window_QT.cpp、window_QT.h兩個文件中與 普通CV庫名字相同的函數 改名 (如加後綴_1),以免發生call衝突!


CV_IMPL int cvWaitKey_1( int arg );
CV_IMPL int cvNamedWindow_1( const char* name, int flags );
CV_IMPL void cvDestroyWindow_1( const char* name );
CV_IMPL void cvDestroyAllWindows_1(void);
CV_IMPL void cvMoveWindow_1( const char* name, int x, int y );
CV_IMPL void cvResizeWindow_1(const char* name, int width, int height );

CV_IMPL int cvCreateTrackbar_1( const char* name_bar, const char* window_name, int* value, int count, CvTrackbarCallback on_change);
CV_IMPL int cvGetTrackbarPos_1( const char* name_bar, const char* window_name );
CV_IMPL void cvSetTrackbarPos_1( const char* name_bar, const char* window_name, int pos );
CV_IMPL void cvSetMouseCallback_1( const char* window_name, CvMouseCallback on_mouse,void* param );
CV_IMPL void cvShowImage_1( const char* name, const CvArr* arr );


一共modify了11個函數,這11個函數可以和 common CV庫 的類似函數共用了。並且還應在window_QT.h中開始部分對函數進行聲明!

Gui線程中用這11個函數沒有問題, 但要在子線程中用,就要 注意,首先必須在gui 線程中 create 新的Qwidge子類的實例( cvNamedWindow_1(  )等11個函數在Qwidge子類的 implement(cpp文件)中),然後再用QWidget::moveToThread( &thread_sub) 把QWidget子類的實例對象 移入 子線程中去,這樣就保證了在GUI主線程中create,在子線程run了。

 

不能是QOBject 的繼承類,只能是QWidget的繼承類!!!

 

如:

在mainwindow.h中定義了兩個類

//*********************************************

class DispThreadObject: public QWidget//QObject// 這裏只能是QWidget的子類,QObject不行!!!否則也會出現上面的錯誤

{

     Q_OBJECT

public:

     DispThreadObject();

     ~DispThreadObject();

     void SetUseDisparity(int useDisparity);

     Sequence seq1;

     Sequence seq2;

     CvStereoBMState  *BMState;

     cv::StereoSGBM  sgbm;

     CImageProcessingThread* thread_A;

     CImageProcessingThread* thread_B;

     bool mm_break;

public slots:

     void slotDispTreadObject();

 

private:

     int m_useDisparity;

 

};

//%%%%%%%%%%%%%

GUI主類

class MyMainWindow: public QMainWindow

{

     Q_OBJECT

public:。。。。。

 

     QThread dispThread;

     DispThreadObject dispObject;

 

};

 

在mainwindow.cpp中

//*********************************************

 

void MyMainWindow::slotDisparityOnline_Thread()

{

。。。。。。

     connect(&dispThread,SIGNAL(started()),&dispObject,SLOT(slotDispTreadObject()));

    dispObject.moveToThread(&dispThread);

    dispThread.start();

。。。。。。

};

//%%%%%%%%%%%%%%%%%%%%%

void DispThreadObject::slotDispTreadObject()

{

     int numSaved=0;   

     std::string filename; 

 

     int width=782;

     int height=582;

     IplImage* imageL = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U, 1);

     IplImage* imageR = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U, 1);

     IplImage* disparity = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U, 1);

     cvNamedWindow_1("display disparity_SGBM",1);    

 

     while(numSaved< m_useDisparity){

         if (mm_break){                  

                   break;

              }

 

         if(!(thread_A->imageQueue.empty()) && !(thread_B->imageQueue.empty())){

 

              seq1.name= (thread_A->imageQueue.front()).name;

              seq1.frame=(thread_A->imageQueue.front()).frame;

              //*********

              seq2.name= (thread_B->imageQueue.front()).name;

              seq2.frame=(thread_B->imageQueue.front()).frame;

 

              //production and consumption model to queue

              thread_A->usedBytes.acquire();

              thread_A->imageQueue.pop();//popping an  used element           

              thread_A->freeBytes.release();

              thread_B->usedBytes.acquire();

              thread_B->imageQueue.pop();

              thread_B->freeBytes.release();

 

              //decide left or right image.                 

              if (seq1.name.compare(0,1,"L")) {

                   //gray image

                   cvCvtColor(seq1.frame,imageL,CV_BGR2GRAY);

                   cvCvtColor(seq2.frame,imageR,CV_BGR2GRAY);

              } else if (seq2.name.compare(0,1,"L")) {

                   cvCvtColor(seq2.frame,imageL,CV_BGR2GRAY);

                   cvCvtColor(seq1.frame,imageR,CV_BGR2GRAY);

              }

 

 

              //combine file name

              char ch = seq1.name.at(seq1.name.size()-5);

              filename="disp";

              filename.append(1,ch);

              filename.append(".png");                 

 

              //int runTime = DisparityAlgorithm::stereoSGBM(imageL,imageR,disparity,sgbm);//

              int runTime = DisparityAlgorithm::stereoBM(imageL,imageR,disparity,BMState);

              cvShowImage_1("display disparity_SGBM",disparity);

              cvWaitKey_1(1);

 

              //cvSaveImage(filename.c_str(),disparity);

 

              //release space

              cvReleaseImage(&seq1.frame);

              cvReleaseImage(&seq2.frame);

              filename.clear();

              ++numSaved;

 

 

              if (0/*stop push_button*/){

                   break;

              }

 

         }

 

     }

     cvReleaseImage(&imageL);

     cvReleaseImage(&imageR);

 

     cvDestroyWindow_1("display disparity_SGBM");    

 

}//

 


 

 

發佈了35 篇原創文章 · 獲贊 12 · 訪問量 43萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章