運(yùn)動(dòng)軌跡捕捉
初次嘗試,先發(fā)個(gè)截圖,實(shí)驗(yàn)用的運(yùn)動(dòng)物體是我的鼠標(biāo)——鼠標(biāo)線被我提著,從外部操控其運(yùn)動(dòng)。
動(dòng)軌跡捕捉.jpg)
附代碼:
1
/*
2
Copyright (C) 2011, coreBugZJ, all rights reserved.
3
4
攝像頭靜止,且光照等環(huán)境不變的情況下,捕捉到運(yùn)動(dòng)物體,并繪出運(yùn)動(dòng)軌跡。
5
6
算法:隨便寫(xiě)的,太弱了,略之。
7
8
VS2010 + OpenCV 2.1 + Win32 API
9
*/
10
11
12
#include "resource.h"
13
#include <Windows.h>
14
15
#include <cv.h>
16
#include <cvaux.h>
17
#include <cvcompat.h>
18
#include <cvinternal.h>
19
#include <cvtypes.h>
20
#include <cvver.h>
21
#include <cvwimage.h>
22
#include <cxcore.h>
23
#include <cxerror.h>
24
#include <cxflann.h>
25
#include <cxmisc.h>
26
#include <cxtypes.h>
27
#include <highgui.h>
28
#include <ml.h>
29
using namespace cv;
30
31
#include <vector>
32
using namespace std;
33
34
#ifdef _DEBUG
35
#include <stdio.h>
36
#endif
37
38
39
#ifdef _DEBUG
40
/* debug */
41
#pragma comment( lib, "cv210d.lib" )
42
#pragma comment( lib, "cvaux210d.lib" )
43
#pragma comment( lib, "cxcore210d.lib" )
44
#pragma comment( lib, "cxts210d.lib" )
45
#pragma comment( lib, "highgui210d.lib" )
46
#pragma comment( lib, "ml210d.lib" )
47
#pragma comment( lib, "opencv_ffmpeg210d.lib" )
48
49
#else
50
/* release */
51
#pragma comment( lib, "cv210.lib" )
52
#pragma comment( lib, "cvaux210.lib" )
53
#pragma comment( lib, "cxcore210.lib" )
54
#pragma comment( lib, "cxts210.lib" )
55
#pragma comment( lib, "highgui210.lib" )
56
#pragma comment( lib, "ml210.lib" )
57
#pragma comment( lib, "opencv_ffmpeg210.lib" )
58
59
#endif
60
61
62
// 記錄軌跡點(diǎn)的數(shù)量
63
#define POINT_NUM 100000
64
// 攝像頭剛啟動(dòng)時(shí),忽略的幀數(shù)
65
#define FRAME_IGN 40
66
// 離散化單元的寬高,單位 像素
67
#define UNIT_LEN 10
68
// 離散化后單元閾值
69
#define UNIT_THRES 10
70
71
72
HWND ghDlg = NULL;
73
INT gWatch = 0;
74
INT gNavig = 0;
75
BOOL gExit = FALSE;
76
77
78
#ifdef _DEBUG
79
FILE *gfp = NULL;
80
char *nameDebug = "調(diào)試窗口";
81
#endif
82
83
84
void GetImageBk( IplImage **pImgBk, IplImage *imgWatch ) {
85
if ( NULL != (*pImgBk) ) {
86
::cvReleaseImage( pImgBk );
87
}
88
*pImgBk = ::cvCreateImage( ::cvGetSize(imgWatch), IPL_DEPTH_8U, 1 );
89
::cvCvtColor( imgWatch, (*pImgBk), CV_BGRA2GRAY );
90
#ifdef _DEBUG
91
::cvShowImage( nameDebug, (*pImgBk) );
92
#endif
93
}
94
95
96
// 返回是否得到新的點(diǎn)
97
// 會(huì)修改 imgWatch
98
BOOL GetNavig( IplImage **pImgNavig, IplImage *imgWatch, IplImage *imgBk ) {
99
static CvPoint pointList[ POINT_NUM ];
100
static int pointNum = 0;
101
102
#define THRES 129
103
#define MAXT 250
104
105
vector< vector< int > > cnt;
106
int cntHeight, cntWidth, cntTot = 0;
107
double sumX = 0, sumY = 0;
108
109
IplImage *imgW = NULL, *imgN = NULL;
110
CvScalar color;
111
BOOL res = FALSE;
112
113
int i, y, x;
114
115
cntHeight = imgWatch->height / UNIT_LEN + 1;
116
cntWidth = imgWatch->width / UNIT_LEN + 1;
117
cnt.resize( cntHeight );
118
for ( y = 0; y < cntHeight; ++y ) {
119
cnt[ y ].resize( cntWidth, 0 );
120
}
121
122
::GetImageBk( &imgW, imgWatch );
123
::GetImageBk( &imgN, imgWatch );
124
::cvAbsDiff( imgW, imgBk, imgN );
125
::cvThreshold( imgN, imgN, THRES, MAXT, CV_THRESH_BINARY );
126
127
for ( y = 0; y < imgN->height; ++y ) {
128
for ( x = 0; x < imgN->width; ++x ) {
129
color = ::cvGet2D( imgN, y, x );
130
if ( color.val[ 0 ] < THRES ) {
131
continue;
132
}
133
++(cnt[ y / UNIT_LEN ][ x / UNIT_LEN ]);
134
}
135
}
136
137
for ( y = 0; y < cntHeight; ++y ) {
138
for ( x = 0; x < cntWidth; ++x ) {
139
i = cnt[ y ][ x ];
140
if ( i >= UNIT_THRES ) {
141
cntTot += i;
142
sumX += i * x * UNIT_LEN;
143
sumY += i * y * UNIT_LEN;
144
}
145
}
146
}
147
148
x = (int)(sumX / cntTot);
149
y = (int)(sumY / cntTot);
150
151
if ( POINT_NUM > pointNum ) {
152
pointList[ pointNum ].x = x;
153
pointList[ pointNum ].y = y;
154
++pointNum;
155
res = TRUE;
156
}
157
158
::cvReleaseImage( &imgW );
159
::cvReleaseImage( &imgN );
160
161
*pImgNavig = imgWatch;
162
color.val[ 0 ] = 0;
163
color.val[ 1 ] = 255;
164
color.val[ 2 ] = 255;
165
color.val[ 3 ] = 0;
166
for ( i = 1; i < pointNum; ++i ) {
167
::cvLine( (*pImgNavig), pointList[ i-1 ], pointList[ i ], color, 8 );
168
}
169
170
#ifdef _DEBUG
171
if ( res ) {
172
}
173
#endif
174
175
return res;
176
}
177
178
179
void DealAllMsg() {
180
MSG msg;
181
while ( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
182
if ( ::IsWindow(ghDlg) && ::IsDialogMessage(ghDlg,&msg) ) {
183
continue;
184
}
185
::TranslateMessage( &msg );
186
::DispatchMessage( &msg );
187
}
188
}
189
190
191
void DelayTime( DWORD delay ) {
192
DWORD start = ::GetTickCount();
193
do {
194
::DealAllMsg();
195
::Sleep( 2 );
196
} while ( (! gExit) && (::GetTickCount() - start < delay) );
197
}
198
199
200
INT_PTR CALLBACK DlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
201
switch ( uMsg ) {
202
case WM_INITDIALOG :
203
::CheckRadioButton( hDlg, IDC_RADIO1, IDC_RADIO3, IDC_RADIO1+gWatch );
204
::CheckRadioButton( hDlg, IDC_RADIO4, IDC_RADIO6, IDC_RADIO4+gNavig );
205
return 1;
206
207
case WM_COMMAND :
208
switch ( LOWORD(wParam) ) {
209
case IDC_RADIO1 :
210
case IDC_RADIO2 :
211
case IDC_RADIO3 :
212
gWatch= LOWORD(wParam) - IDC_RADIO1;
213
::CheckRadioButton( hDlg, IDC_RADIO1, IDC_RADIO3, IDC_RADIO1+gWatch );
214
return 1;
215
case IDC_RADIO4 :
216
case IDC_RADIO5 :
217
case IDC_RADIO6 :
218
gNavig = LOWORD(wParam) - IDC_RADIO4;
219
::CheckRadioButton( hDlg, IDC_RADIO4, IDC_RADIO6, IDC_RADIO4+gNavig );
220
return 1;
221
case IDCANCEL :
222
gExit = TRUE;
223
return 1;
224
}
225
break;
226
}
227
return 0;
228
}
229
230
231
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR szCmd, INT nShow ) {
232
char *nameWatch = "監(jiān)視窗口";
233
char *nameNavig = "軌跡窗口";
234
CvCapture *cap = NULL;
235
IplImage *imgWatch = NULL, *imgNavig = NULL, *imgBk = NULL;
236
int frame = 0;
237
238
cap = ::cvCreateCameraCapture( -1 );
239
::DealAllMsg();
240
if ( NULL == cap ) {
241
::MessageBox( NULL, TEXT("攝像頭錯(cuò)誤"), TEXT("錯(cuò)誤"), MB_ICONERROR | MB_OK );
242
return 0;
243
}
244
245
::cvNamedWindow( nameWatch);
246
::DealAllMsg();
247
::cvNamedWindow( nameNavig );
248
::DealAllMsg();
249
250
ghDlg = ::CreateDialogParam( hInst, MAKEINTRESOURCE(IDD_GARAGE_DIALOG), NULL, DlgProc, 0 );
251
::ShowWindow( ghDlg, SW_SHOW );
252
::DealAllMsg();
253
254
#ifdef _DEBUG
255
gfp = ::fopen( "debug.txt", "wt" );
256
::cvNamedWindow( nameDebug );
257
#endif
258
259
for ( ; ; ) {
260
imgWatch= ::cvQueryFrame( cap );
261
::DealAllMsg();
262
if ( NULL == imgWatch) {
263
break;
264
}
265
266
if ( frame < FRAME_IGN ) {
267
++frame;
268
}
269
if ( frame == FRAME_IGN ) {
270
++frame;
271
::GetImageBk( &imgBk, imgWatch );
272
}
273
274
switch ( gWatch) {
275
case 0 :
276
::cvShowImage( nameWatch, imgWatch );
277
break;
278
case 1 :
279
break;
280
case 2 :
281
::cvDestroyWindow( nameWatch );
282
break;
283
}
284
::DealAllMsg();
285
if ( gExit ) {
286
break;
287
}
288
289
if ( frame <= FRAME_IGN ) {
290
imgNavig = NULL;
291
}
292
else {
293
if ( ::GetNavig( &imgNavig, imgWatch, imgBk ) ) {
294
}
295
}
296
297
switch ( gNavig ) {
298
case 0 :
299
::cvShowImage( nameNavig, imgNavig );
300
break;
301
case 1 :
302
break;
303
case 2 :
304
::cvDestroyWindow( nameNavig );
305
break;
306
}
307
::DealAllMsg();
308
if ( gExit ) {
309
break;
310
}
311
}
312
313
::cvReleaseImage( &imgBk );
314
315
::DestroyWindow( ghDlg );
316
317
::cvDestroyWindow( nameNavig );
318
::cvDestroyWindow( nameWatch );
319
320
::cvReleaseCapture( &cap );
321
322
#ifdef _DEBUG
323
::cvDestroyWindow( nameDebug );
324
::fclose( gfp );
325
#endif
326
327
return 0;
328
}
329

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

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

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 "運(yùn)動(dòng)軌跡捕捉"
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 "關(guān)閉",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 "關(guān)閉",IDC_RADIO6,"Button",BS_AUTORADIOBUTTON,185,90,32,10
65
GROUPBOX "監(jiān)視窗口",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-18 20:05 coreBugZJ 閱讀(12081) 評(píng)論(1) 編輯 收藏 引用 所屬分類(lèi): VideoImage 、Algorithm 、Windows 、UI