1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include "precomp.hpp"
43
44 #ifdef WIN32
45
46 /****************** Capturing video from camera via CMU lib *******************/
47
48 #ifdef HAVE_CMU1394
49
50 // This firewire capability added by Philip Gruebele (pgruebele@cox.net).
51 // For this to work you need to install the CMU firewire DCAM drivers,
52 // located at http://www-2.cs.cmu.edu/~iwan/1394/.
53 #include "1394camera.h"
54
55 class CvCaptureCAM_CMU : public CvCapture
56 {
57 public:
CvCaptureCAM_CMU()58 CvCaptureCAM_CMU()
59 {
60 index = -1;
61 image = 0;
62 }
63
~CvCaptureCAM_CMU()64 virtual ~CvCaptureCAM_CMU()
65 {
66 close();
67 }
68
69 virtual bool open(int cameraId);
70 virtual void close();
71 virtual double getProperty(int) const;
72 virtual bool setProperty(int, double);
73 virtual bool grabFrame();
74 virtual IplImage* retrieveFrame(int);
75
76 protected:
77 C1394Camera* camera();
78 CvSize getSize();
79 int getDepth();
80 int getNChannels();
81
82 bool setVideoSize(int, int);
83 bool setMode(int mode);
84 bool setFrameRate(int rate);
85 bool setFormat(int format);
86
87 int fps; // 0-5
88 int mode; // 0-7
89 int format; // 0-2, 7 ?
90 int index;
91 IplImage* image;
92 };
93
94 // CMU 1394 camera stuff.
95 // This firewire capability added by Philip Gruebele (pgruebele@cox.net)
96 // and modified by Roman Stanchak (rstanchak@yahoo.com).
97 // For this to work you need to install the CMU firewire DCAM drivers,
98 // located at http://www-2.cs.cmu.edu/~iwan/1394/.
99 #define CMU_MAX_CAMERAS 20
100 int CMU_numCameras = 0;
101 int CMU_numActiveCameras = 0;
102 bool CMU_useCameraFlags[CMU_MAX_CAMERAS];
103 C1394Camera *CMU_theCamera = 0;
104
105 // stupid defines for mode, format, FPS
106 #define CV_CAP_IEEE1394_FPS_1_875 0
107 #define CV_CAP_IEEE1394_FPS_3_75 1
108 #define CV_CAP_IEEE1394_FPS_7_5 2
109 #define CV_CAP_IEEE1394_FPS_15 3
110 #define CV_CAP_IEEE1394_FPS_30 4
111 #define CV_CAP_IEEE1394_FPS_60 5
112
113 // index by size, color
114 #define CV_CAP_IEEE1394_COLOR_MONO 0
115 #define CV_CAP_IEEE1394_COLOR_MONO16 1
116 #define CV_CAP_IEEE1394_COLOR_YUV444 2
117 #define CV_CAP_IEEE1394_COLOR_YUV422 3
118 #define CV_CAP_IEEE1394_COLOR_YUV411 4
119 #define CV_CAP_IEEE1394_COLOR_RGB 5
120
121 #define CV_CAP_IEEE1394_SIZE_160X120 0
122 #define CV_CAP_IEEE1394_SIZE_320X240 1
123 #define CV_CAP_IEEE1394_SIZE_640X480 2
124 #define CV_CAP_IEEE1394_SIZE_800X600 3
125 #define CV_CAP_IEEE1394_SIZE_1024X768 4
126 #define CV_CAP_IEEE1394_SIZE_1280X960 5
127 #define CV_CAP_IEEE1394_SIZE_1600X1200 6
128
129 // given color, size, output format
130 // 1 16 444 422 411 RGB
131 static char CV_CAP_IEEE1394_FORMAT[7][6] =
132 {
133 {-1, -1, 0, -1, -1, -1}, // 160x120
134 {-1, -1, -1, 0, -1, -1}, // 320x240
135 { 0, 0, -1, 0, 0, 0}, // 640x480
136 { 1, 1, -1, 1, -1, 1}, // 800x600
137 { 1, 1, -1, 1, -1, 1}, // 1024x768
138 { 2, 2, -1, 2, -1, 2}, // 1280x960
139 { 2, 2, -1, 2, -1, 2} // 1600x1200
140 };
141
142 // given color, size, output corresponding mode
143 static char CV_CAP_IEEE1394_MODE[7][6] =
144 {
145 {-1, -1, 0, -1, -1, -1}, // 160x120
146 {-1, -1, -1, 1, -1, -1}, // 320x240
147 { 5, 6, -1, 3, 2, 4}, // 640x480
148 { 2, 6, -1, 0, -1, 1}, // 800x600
149 { 5, 7, -1, 3, -1, 4}, // 1024x768
150 { 2, 6, -1, 0, -1, 1}, // 1280x960
151 { 5, 7, -1, 3, -1, 4} // 1600x1200
152 };
153
154 // given format, mode, return COLOR
155 static char CV_CAP_IEEE1394_COLOR[2][8] =
156 {
157 {
158 CV_CAP_IEEE1394_COLOR_YUV444,
159 CV_CAP_IEEE1394_COLOR_YUV422,
160 CV_CAP_IEEE1394_COLOR_YUV411,
161 CV_CAP_IEEE1394_COLOR_YUV422,
162 CV_CAP_IEEE1394_COLOR_RGB,
163 CV_CAP_IEEE1394_COLOR_MONO,
164 CV_CAP_IEEE1394_COLOR_MONO16
165 },
166 {
167 CV_CAP_IEEE1394_COLOR_YUV422,
168 CV_CAP_IEEE1394_COLOR_RGB,
169 CV_CAP_IEEE1394_COLOR_MONO,
170 CV_CAP_IEEE1394_COLOR_YUV422,
171 CV_CAP_IEEE1394_COLOR_RGB,
172 CV_CAP_IEEE1394_COLOR_MONO,
173 CV_CAP_IEEE1394_COLOR_MONO16,
174 CV_CAP_IEEE1394_COLOR_MONO16
175 }
176 };
177
178 // convert frame rate to suitable enum
179 /*static int icvFrameRateToIndex_CMU(double framerate){
180 if(framerate > 30) return CV_CAP_IEEE1394_FPS_60;
181 else if(framerate > 15) return CV_CAP_IEEE1394_FPS_30;
182 else if(framerate > 7.5) return CV_CAP_IEEE1394_FPS_15;
183 else if(framerate > 3.75) return CV_CAP_IEEE1394_FPS_7_5;
184 else if(framerate > 1.875) return CV_CAP_IEEE1394_FPS_3_75;
185 return CV_CAP_IEEE1394_FPS_1_875;
186 }*/
187
188 #if _MSC_VER >= 1200
189 #pragma comment(lib,"1394camera.lib")
190 #endif
191
camera()192 C1394Camera* CvCaptureCAM_CMU::camera()
193 {
194 return CMU_theCamera && index >= 0 ? &CMU_theCamera[index] : 0;
195 }
196
197 // return the size of the image
getSize()198 CvSize CvCaptureCAM_CMU::getSize()
199 {
200 C1394Camera* cmucam = camera();
201 unsigned long width = 0, height = 0;
202 cmucam->GetVideoFrameDimensions( &width, &height );
203 return cvSize((int)width, (int)height);
204 }
205
206 // return the opencv depth flag corresponding to the camera format
getDepth()207 int CvCaptureCAM_CMU::getDepth()
208 {
209 C1394Camera* cmucam = camera();
210 int format = cmucam->GetVideoFormat();
211 int mode = cmucam->GetVideoMode();
212
213 // TODO
214 if( format==7 ) {
215 assert(0);
216 return 1;
217 }
218 // irrelvant to depth
219 if( format > 1 )
220 format = 1;
221
222 if( CV_CAP_IEEE1394_COLOR[format][mode]==CV_CAP_IEEE1394_COLOR_MONO16 )
223 return IPL_DEPTH_16S;
224
225 return IPL_DEPTH_8U;
226 }
227
228 // return the number of channels for camera
getNChannels()229 int CvCaptureCAM_CMU::getNChannels()
230 {
231 C1394Camera* cmucam = camera();
232 int format = cmucam->GetVideoFormat();
233 int mode = cmucam->GetVideoMode();
234
235 if( format==7 ){
236 assert(0);
237 return 1;
238 }
239
240 // irrelvant to nchannels
241 if( format > 1 )
242 format = 1;
243
244 switch(CV_CAP_IEEE1394_COLOR[format][mode]){
245 case CV_CAP_IEEE1394_COLOR_RGB:
246 return 3;
247 case CV_CAP_IEEE1394_COLOR_MONO:
248 case CV_CAP_IEEE1394_COLOR_MONO16:
249 return 1;
250 case CV_CAP_IEEE1394_COLOR_YUV422:
251 case CV_CAP_IEEE1394_COLOR_YUV444:
252 case CV_CAP_IEEE1394_COLOR_YUV411:
253 return 3;
254 default:
255 ;
256 }
257 return -1;
258 }
259
open(int _index)260 bool CvCaptureCAM_CMU::open( int _index )
261 {
262 close();
263
264 // if first time, then allocate all available cameras
265 if( CMU_numCameras == 0 )
266 {
267 CMU_numActiveCameras = 0;
268 CMU_theCamera = new C1394Camera[CMU_MAX_CAMERAS];
269
270 ////////////////////////////////////////////////////////////////////////////////////////////////////////
271 // create all cameras
272 try
273 {
274 // create camera0
275 if( CMU_theCamera[0].CheckLink() != CAM_SUCCESS )
276 throw 1;
277
278 // we have one pin per camera
279 CMU_numCameras = CMU_theCamera[0].GetNumberCameras();
280
281 // allocate remaining cameras
282 for(int i = 1; i < CMU_numCameras && i<CMU_MAX_CAMERAS; i++ )
283 {
284 CMU_useCameraFlags[i] = false;
285 if (CMU_theCamera[i].CheckLink() != CAM_SUCCESS)
286 throw 1;
287 }
288 }
289 catch (...)
290 {
291 // free any allocated cameras
292 // ...
293 CMU_numCameras = 0;
294 return false;
295 }
296 }
297
298 try
299 {
300 CvSize size;
301
302 // pick first unused camera
303 if(_index==-1){
304 for(int i = 0; i < CMU_numCameras; i++ )
305 {
306 if( !CMU_useCameraFlags[i] ){
307 _index = i;
308 break;
309 }
310 }
311 }
312
313 // no empty camera found
314 if (_index==-1)
315 throw 1;
316
317 if (CMU_theCamera[_index].SelectCamera(_index) != CAM_SUCCESS)
318 throw 2;
319
320 if (CMU_theCamera[_index].InitCamera() != CAM_SUCCESS)
321 throw 3;
322
323 // set initial format -- try to pick best frame rate first, then color, then size
324 bool found_format = false;
325 for (int rate=5; rate>=0 && !found_format; rate--)
326 {
327 for (int color=CV_CAP_IEEE1394_COLOR_RGB; color>=0 && !found_format; color--)
328 {
329 for (int size=CV_CAP_IEEE1394_SIZE_1600X1200; size>=0 && !found_format; size--)
330 {
331 int format = CV_CAP_IEEE1394_FORMAT[size][color];
332 int mode = CV_CAP_IEEE1394_MODE[size][color];
333 if (format!=-1 && mode!=-1 &&
334 CMU_theCamera[_index].HasVideoFrameRate(format,mode,rate))
335 {
336 CMU_theCamera[_index].SetVideoFormat(format);
337 CMU_theCamera[_index].SetVideoMode(mode);
338 CMU_theCamera[_index].SetVideoFrameRate(rate);
339 found_format = (CMU_theCamera[_index].StartImageAcquisition() == CAM_SUCCESS);
340 }
341 }
342 }
343 }
344
345 // try format 7
346 if(!found_format){
347 CMU_theCamera[_index].SetVideoFormat(7);
348 CMU_theCamera[_index].SetVideoMode(0);
349 if(CMU_theCamera[_index].StartImageAcquisition() != CAM_SUCCESS){
350 // no format found
351 throw 9;
352 }
353 }
354
355 index = _index;
356 size = getSize();
357 // allocate image frame
358 image = cvCreateImage( size, 8, 3 );
359 cvZero(image);
360
361 // successfully activated camera
362 CMU_numActiveCameras++;
363 CMU_useCameraFlags[_index] = true;
364 }
365 catch ( int )
366 {
367 return false;
368 }
369
370 return true;
371 }
372
close()373 void CvCaptureCAM_CMU::close()
374 {
375 C1394Camera* cmucam = camera();
376 if( cmucam )
377 {
378 cvReleaseImage( &image );
379 cmucam->StopImageAcquisition();
380 CMU_useCameraFlags[index] = false;
381 index = -1;
382
383 if( --CMU_numActiveCameras == 0 )
384 {
385 delete[] CMU_theCamera;
386 CMU_theCamera = 0;
387 CMU_numCameras = 0;
388 }
389 }
390 }
391
392
grabFrame()393 bool CvCaptureCAM_CMU::grabFrame()
394 {
395 C1394Camera* cmucam = camera();
396 return cmucam ? cmucam->AcquireImage() == CAM_SUCCESS : false;
397 }
398
399 /*static void swapRedBlue(IplImage * im)
400 {
401 uchar * ptr = (uchar *) im->imageData;
402 uchar t;
403 for(int i=0; i<im->height; i++){
404 ptr = (uchar *) im->imageData+im->widthStep*i;
405 for(int j=0; j<im->width; j++){
406 t = ptr[0];
407 ptr[0] = ptr[2];
408 ptr[2] = t;
409 ptr+=3;
410 }
411 }
412 }*/
413
retrieveFrame(int)414 IplImage* CvCaptureCAM_CMU::retrieveFrame(int)
415 {
416 C1394Camera* cmucam = camera();
417 if( !cmucam )
418 return 0;
419 cmucam->getRGB((uchar*)image->imageData, image->imageSize);
420 cvConvertImage( image, image, CV_CVTIMG_SWAP_RB );
421 return image;
422 }
423
424
getProperty(int property_id) const425 double CvCaptureCAM_CMU::getProperty( int property_id ) const
426 {
427 C1394Camera* cmucam = camera();
428 if( !cmucam )
429 return 0;
430 switch( property_id )
431 {
432 case CV_CAP_PROP_FRAME_WIDTH:
433 return image->width;
434 case CV_CAP_PROP_FRAME_HEIGHT:
435 return image->height;
436 case CV_CAP_PROP_FPS:
437 return cmucam->GetVideoFrameRate();
438 case CV_CAP_PROP_MODE:
439 return cmucam->GetVideoMode();
440 case CV_CAP_PROP_FORMAT:
441 return cmucam->GetVideoFormat();
442 }
443 return 0;
444 }
445
setVideoSize(int,int)446 bool CvCaptureCAM_CMU::setVideoSize(int, int)
447 {
448 return false;
449 }
450
setMode(int mode)451 bool CvCaptureCAM_CMU::setMode(int mode)
452 {
453 int format;
454 C1394Camera* cmucam = camera();
455 if( !cmucam )
456 return false;
457 format = cmucam->GetVideoFormat();
458 if( mode < 0 || mode > 7 || !cmucam->HasVideoMode(format, mode))
459 return false;
460 cmucam->StopImageAcquisition();
461 cmucam->SetVideoMode(mode);
462 cmucam->StartImageAcquisition();
463 return true;
464 }
465
setFrameRate(int rate)466 bool CvCaptureCAM_CMU::setFrameRate(int rate)
467 {
468 int format, mode;
469 C1394Camera* cmucam = camera();
470 if( !cmucam )
471 return false;
472 mode = cmucam->GetVideoMode();
473 format = cmucam->GetVideoFormat();
474 if( rate < 0 || rate > 5 || !cmucam->HasVideoFrameRate(format, mode, rate) )
475 return false;
476 cmucam->StopImageAcquisition();
477 cmucam->SetVideoFrameRate(rate);
478 cmucam->StartImageAcquisition();
479 return true;
480 }
481
setFormat(int format)482 bool CvCaptureCAM_CMU::setFormat(int format)
483 {
484 C1394Camera* cmucam = camera();
485 if( !cmucam )
486 return false;
487 if( format < 0 || format > 2 || !cmucam->HasVideoFormat(format) )
488 return false;
489 cmucam->StopImageAcquisition();
490 cmucam->SetVideoFormat(format);
491 cmucam->StartImageAcquisition();
492 return true;
493 }
494
setProperty(int property_id,double value)495 bool CvCaptureCAM_CMU::setProperty( int property_id, double value )
496 {
497 bool retval = false;
498 int ival = cvRound(value);
499 C1394Camera* cmucam = camera();
500 if( !cmucam )
501 return false;
502
503 switch (property_id) {
504 case CV_CAP_PROP_FRAME_WIDTH:
505 case CV_CAP_PROP_FRAME_HEIGHT:
506 {
507 int width, height;
508 if (property_id == CV_CAP_PROP_FRAME_WIDTH)
509 {
510 width = ival;
511 height = width*3/4;
512 }
513 else {
514 height = ival;
515 width = height*4/3;
516 }
517 retval = setVideoSize(width, height);
518 }
519 break;
520 case CV_CAP_PROP_FPS:
521 retval = setFrameRate(ival);
522 break;
523 case CV_CAP_PROP_MODE:
524 retval = setMode(ival);
525 break;
526 case CV_CAP_PROP_FORMAT:
527 retval = setFormat(ival);
528 break;
529 }
530
531 // resize image if its not the right size anymore
532 CvSize size = getSize();
533 if( !image || image->width != size.width || image->height != size.height )
534 {
535 cvReleaseImage( &image );
536 image = cvCreateImage( size, 8, 3 );
537 }
538 return retval;
539 }
540
cvCreateCameraCapture_CMU(int index)541 CvCapture * cvCreateCameraCapture_CMU (int index)
542 {
543 CvCaptureCAM_CMU* capture = new CvCaptureCAM_CMU;
544 if( capture->open(index) )
545 return capture;
546 delete capture;
547 return 0;
548 }
549
550 #endif // CMU
551 #endif // WIN32
552