嘗試 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, 0, 0, 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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

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

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

posted on 2011-11-06 17:59 coreBugZJ 閱讀(2224) 評論(0) 編輯 收藏 引用 所屬分類: VideoImage 、Windows