尝试 OpenCV 摄像头 与 Windows 消息机制

尝试 OpenCV 摄像头 与 Windows 消息机制


    OpenCV 的 highgui 提供了简单的界面,然而在 Windows 下,它并未将消息机制封装的足够好,在使用的时候,若不考虑到消息机制,很容易使界面死掉,同时 OpenCV 本身的运转也会出问题。


    Windows 下,界面的正常运作需要大量的消息传递与处理,然而 OpenCV 的函数,几乎都与消息无关,目前我只知道 cvWaitKey() 会接收并转发本线程的消息(恕我无知),但只仅限于被调用后的等待时间内,所以并不能完全保证消息机制的正常运作。程序至少需要考虑到主动接收与转发消息,以确保界面的正常运作。(也许这可以解释,为什么许多示例程序中都调用了 cvWaitKey() 函数。)


    Windows 下的消息是线程相关的,启动新线程又会引出更多的问题。


    下面程序从摄像头获取输入,并在窗口中显示。三个窗口使用一个线程。


    我尝试过创建新线程,在新线程中使用 highgui 创建窗口,显示图像,然而,窗口的大小正确,却显示一片灰色(求指教!!)。

  

 

 

 附源代码:
由于线程关系,我使用了最朴素的 Win32 API 。
OpenCV 2.1 + VS2010

  1 #include  " resource.h "
  2 #include  < Windows.h >
  3 #include  < highgui.h >
  4
  5
  6 #ifdef  _DEBUG
  7 /**/ /* debug */
  8
  9 #pragma comment( lib,  " cv210d.lib "  )
 10 #pragma comment( lib,  " cvaux210d.lib "  )
 11 #pragma comment( lib,  " cxcore210d.lib "  )
 12 #pragma comment( lib,  " cxts210d.lib "  )
 13 #pragma comment( lib,  " highgui210d.lib "  )
 14 #pragma comment( lib,  " ml210d.lib "  )
 15 #pragma comment( lib,  " opencv_ffmpeg210d.lib "  )
 16
 17
 18 #else
 19 /**/ /* release */
 20
 21 #pragma comment( lib,  " cv210.lib "  )
 22 #pragma comment( lib,  " cvaux210.lib "  )
 23 #pragma comment( lib,  " cxcore210.lib "  )
 24 #pragma comment( lib,  " cxts210.lib "  )
 25 #pragma comment( lib,  " highgui210.lib "  )
 26 #pragma comment( lib,  " ml210.lib "  )
 27 #pragma comment( lib,  " opencv_ffmpeg210.lib "  )
 28
 29
 30 #endif
 31
 32
 33 HWND  ghDlg   =  NULL;
 34 INT   gleft   =   0 ;
 35 INT   gright  =   0 ;
 36 BOOL  gexit   =  FALSE;
 37
 38
 39 void  DealAllMsg()  {
 40        MSG msg;
 41        while ( ::PeekMessage( &msg, NULL, 00, PM_REMOVE ) ) {
 42                if ( ::IsWindow(ghDlg) && ::IsDialogMessage(ghDlg,&msg) ) {
 43                        continue;
 44                }

 45                ::TranslateMessage( &msg );
 46                ::DispatchMessage( &msg );
 47        }

 48}

 49
 50
 51 void  DelayTime( DWORD delay )  {
 52        DWORD start = ::GetTickCount();
 53        do {
 54                ::DealAllMsg();
 55                ::Sleep( 2 );
 56        }
 while ( (! gexit) && (::GetTickCount() - start < delay) );
 57}

 58
 59
 60 INT_PTR  CALLBACK DlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )  {
 61        switch ( uMsg ) {
 62        case WM_INITDIALOG : 
 63                ::CheckRadioButton( hDlg, IDC_RADIO1, IDC_RADIO3, IDC_RADIO1+gleft  );
 64                ::CheckRadioButton( hDlg, IDC_RADIO4, IDC_RADIO6, IDC_RADIO4+gright );
 65                return 1;
 66
 67        case WM_COMMAND : 
 68                switch ( LOWORD(wParam) ) {
 69                case IDC_RADIO1 : 
 70                case IDC_RADIO2 : 
 71                case IDC_RADIO3 : 
 72                        gleft = LOWORD(wParam) - IDC_RADIO1;
 73                        ::CheckRadioButton( hDlg, IDC_RADIO1, IDC_RADIO3, IDC_RADIO1+gleft );
 74                        return 1;
 75                case IDC_RADIO4 : 
 76                case IDC_RADIO5 : 
 77                case IDC_RADIO6 : 
 78                        gright = LOWORD(wParam) - IDC_RADIO4;
 79                        ::CheckRadioButton( hDlg, IDC_RADIO4, IDC_RADIO6, IDC_RADIO4+gright );
 80                        return 1;
 81                case IDCANCEL : 
 82                        gexit = TRUE;
 83                        return 1;
 84                }

 85                break;
 86        }

 87        return 0;
 88}

 89
 90
 91 INT  WINAPI  WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR szCmd, INT nShow )  {
 92        char  *nameleft  = "左窗口";
 93        char  *nameright = "右窗口";
 94        CvCapture *cap = NULL;
 95        IplImage  *imgleft = NULL, *imgright = NULL;
 96        int i;
 97
 98        cap = ::cvCreateCameraCapture( -1 );
 99        ::DealAllMsg();
100        if ( NULL == cap ) {
101                ::MessageBox( NULL, TEXT("摄像头错误"), TEXT("错误"), MB_ICONERROR | MB_OK );
102                return 0;
103        }

104
105        ::cvNamedWindow( nameleft );
106        ::DealAllMsg();
107        ::cvNamedWindow( nameright );
108        ::DealAllMsg();
109
110        ghDlg = ::CreateDialogParam( hInst, MAKEINTRESOURCE(IDD_GARAGE_DIALOG), NULL, DlgProc, 0 );
111        ::ShowWindow( ghDlg, SW_SHOW );
112        ::DealAllMsg();
113
114        for ( ; ; ) {
115                for ( i = 0; i < 1++i ) {
116                        imgleft = ::cvQueryFrame( cap );
117                        ::DealAllMsg();
118                        if ( NULL == imgleft ) {
119                                break;
120                        }

121                }

122                if ( NULL == imgleft ) {
123                        break;
124                }

125
126                switch ( gleft ) {
127                case 0 : 
128                        ::cvShowImage( nameleft, imgleft );
129                        break;
130                case 1 : 
131                        break;
132                case 2 : 
133                        ::cvDestroyWindow( nameleft );
134                        break;
135                }

136                ::DealAllMsg();
137                if ( gexit ) {
138                        break;
139                }

140
141                imgright = imgleft; // imgright = func( imgleft );
142                ::DealAllMsg();
143
144                switch ( gright ) {
145                case 0 : 
146                        ::cvShowImage( nameright, imgright );
147                        break;
148                case 1 : 
149                        break;
150                case 2 : 
151                        ::cvDestroyWindow( nameright );
152                        break;
153                }

154                ::DealAllMsg();
155                if ( gexit ) {
156                        break;
157                }

158        }

159
160        ::DestroyWindow( ghDlg );
161
162        ::cvDestroyWindow( nameright );
163        ::cvDestroyWindow( nameleft );
164
165        ::cvReleaseCapture( &cap );
166
167        return 0;
168}

169

 

 1 // {{NO_DEPENDENCIES}}
 2 //  Microsoft Visual C++ generated include file.
 3 //  Used by Garage.rc
 4 //
 5 #define  IDD_GARAGE_DIALOG               101
 6 #define  IDC_RADIO1                      1001
 7 #define  IDC_RADIO2                      1002
 8 #define  IDC_RADIO3                      1003
 9 #define  IDC_RADIO4                      1004
10 #define  IDC_RADIO5                      1005
11 #define  IDC_RADIO6                      1006
12
13
14 //  Next default values for new objects
15 //  
16 #ifdef APSTUDIO_INVOKED
17 #ifndef APSTUDIO_READONLY_SYMBOLS
18 #define  _APS_NEXT_RESOURCE_VALUE        102
19 #define  _APS_NEXT_COMMAND_VALUE         40001
20 #define  _APS_NEXT_CONTROL_VALUE         1007
21 #define  _APS_NEXT_SYMED_VALUE           101
22 #endif
23 #endif
24

 

  1 //  Microsoft Visual C++ generated resource script.
  2 //
  3 #include  " resource.h "
  4
  5 #define  APSTUDIO_READONLY_SYMBOLS
  6 /**/ /////////////////////////////////////////////////////////////////////////////
  7 //
  8 //  Generated from the TEXTINCLUDE 2 resource.
  9 //
 10 #include  " afxres.h "
 11
 12 /**/ /////////////////////////////////////////////////////////////////////////////
 13 #undef  APSTUDIO_READONLY_SYMBOLS
 14
 15 /**/ /////////////////////////////////////////////////////////////////////////////
 16 //  Chinese (Simplified, PRC) resources
 17
 18 #if  !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
 19 LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
 20
 21 #ifdef APSTUDIO_INVOKED
 22 /**/ /////////////////////////////////////////////////////////////////////////////
 23 //
 24 //  TEXTINCLUDE
 25 //
 26
 27 1  TEXTINCLUDE 
 28 BEGIN
 29      " resource.h\0 "
 30 END
 31
 32 2  TEXTINCLUDE 
 33 BEGIN
 34      " #include  "" afxres.h "" \r\n "
 35      " \0 "
 36 END
 37
 38 3  TEXTINCLUDE 
 39 BEGIN
 40      " \r\n "
 41      " \0 "
 42 END
 43
 44 #endif      //  APSTUDIO_INVOKED
 45
 46
 47 /**/ /////////////////////////////////////////////////////////////////////////////
 48 //
 49 //  Dialog
 50 //
 51
 52 IDD_GARAGE_DIALOG DIALOGEX  0 0 266 156
 53 STYLE DS_SETFONT  |  DS_FIXEDSYS  |  WS_POPUP  |  WS_VISIBLE  |  WS_CAPTION  |  WS_THICKFRAME
 54 EXSTYLE WS_EX_APPWINDOW
 55 CAPTION  " OpenCV 摄像头 - 尝试 "
 56 FONT  8 " MS Shell Dlg " 0 0 0x1
 57 BEGIN
 58     DEFPUSHBUTTON    " 退出 " ,IDCANCEL, 209 , 135 , 50 , 14
 59     CONTROL          " 播放 " ,IDC_RADIO1, " Button " ,BS_AUTORADIOBUTTON  |  WS_GROUP, 40 , 40 , 32 , 10
 60     CONTROL          " 暂停 " ,IDC_RADIO2, " Button " ,BS_AUTORADIOBUTTON, 40 , 65 , 32 , 10
 61     CONTROL          " 关闭 " ,IDC_RADIO3, " Button " ,BS_AUTORADIOBUTTON, 40 , 90 , 32 , 10
 62     CONTROL          " 播放 " ,IDC_RADIO4, " Button " ,BS_AUTORADIOBUTTON  |  WS_GROUP, 185 , 40 , 32 , 10
 63     CONTROL          " 暂停 " ,IDC_RADIO5, " Button " ,BS_AUTORADIOBUTTON, 185 , 65 , 32 , 10
 64     CONTROL          " 关闭 " ,IDC_RADIO6, " Button " ,BS_AUTORADIOBUTTON, 185 , 90 , 32 , 10
 65     GROUPBOX         " 左窗口 " ,IDC_STATIC, 23 , 20 , 65 , 86
 66     GROUPBOX         " 右窗口 " ,IDC_STATIC, 168 , 20 , 65 , 86
 67 END
 68
 69
 70 /**/ /////////////////////////////////////////////////////////////////////////////
 71 //
 72 //  DESIGNINFO
 73 //
 74
 75 #ifdef APSTUDIO_INVOKED
 76 GUIDELINES DESIGNINFO
 77 BEGIN
 78     IDD_GARAGE_DIALOG, DIALOG
 79     BEGIN
 80         LEFTMARGIN,  7
 81         RIGHTMARGIN,  259
 82         TOPMARGIN,  7
 83         BOTTOMMARGIN,  149
 84     END
 85 END
 86 #endif      //  APSTUDIO_INVOKED
 87
 88 #endif      //  Chinese (Simplified, PRC) resources
 89 /**/ /////////////////////////////////////////////////////////////////////////////
 90
 91
 92
 93 #ifndef APSTUDIO_INVOKED
 94 /**/ /////////////////////////////////////////////////////////////////////////////
 95 //
 96 //  Generated from the TEXTINCLUDE 3 resource.
 97 //
 98
 99
100 /**/ /////////////////////////////////////////////////////////////////////////////
101 #endif      //  not APSTUDIO_INVOKED
102
103



 

你可能感兴趣的:(尝试 OpenCV 摄像头 与 Windows 消息机制)