coreBugZJ

此 blog 已弃。

尝试 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
 33HWND  ghDlg  = NULL;
 34INT   gleft  = 0;
 35INT   gright = 0;
 36BOOL  gexit  = FALSE;
 37
 38
 39void 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
 51void DelayTime( DWORD delay ) {
 52        DWORD start = ::GetTickCount();
 53        do {
 54                ::DealAllMsg();
 55                ::Sleep( 2 );
 56        }
 while ( (! gexit) && (::GetTickCount() - start < delay) );
 57}

 58
 59
 60INT_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
 91INT  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)
 19LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
 20
 21#ifdef APSTUDIO_INVOKED
 22/////////////////////////////////////////////////////////////////////////////
 23//
 24// TEXTINCLUDE
 25//
 26
 271 TEXTINCLUDE 
 28BEGIN
 29    "resource.h\0"
 30END
 31
 322 TEXTINCLUDE 
 33BEGIN
 34    "#include ""afxres.h""\r\n"
 35    "\0"
 36END
 37
 383 TEXTINCLUDE 
 39BEGIN
 40    "\r\n"
 41    "\0"
 42END
 43
 44#endif    // APSTUDIO_INVOKED
 45
 46
 47/////////////////////////////////////////////////////////////////////////////
 48//
 49// Dialog
 50//
 51
 52IDD_GARAGE_DIALOG DIALOGEX 00266156
 53STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_THICKFRAME
 54EXSTYLE WS_EX_APPWINDOW
 55CAPTION "OpenCV 摄像头 - 尝试"
 56FONT 8"MS Shell Dlg"000x1
 57BEGIN
 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
 67END
 68
 69
 70/////////////////////////////////////////////////////////////////////////////
 71//
 72// DESIGNINFO
 73//
 74
 75#ifdef APSTUDIO_INVOKED
 76GUIDELINES DESIGNINFO
 77BEGIN
 78    IDD_GARAGE_DIALOG, DIALOG
 79    BEGIN
 80        LEFTMARGIN, 7
 81        RIGHTMARGIN, 259
 82        TOPMARGIN, 7
 83        BOTTOMMARGIN, 149
 84    END
 85END
 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



 

posted on 2011-11-06 17:59 coreBugZJ 阅读(2195) 评论(0)  编辑 收藏 引用 所属分类: VideoImageWindows


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理