现在的位置: 首页 > 综合 > 正文

OpenCV+中把cvNamedWindow(char*,int+flag)创建的窗口+同时显示QT性能+或+关闭掉Qt性能

2013年09月21日 ⁄ 综合 ⁄ 共 5891字 ⁄ 字号 评论关闭

 

       要把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");    

 

}//

 

 

 

抱歉!评论已关闭.