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 (at) 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: 58 CvCaptureCAM_CMU() 59 { 60 index = -1; 61 image = 0; 62 } 63 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 (at) cox.net) 96 // and modified by Roman Stanchak (rstanchak (at) 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 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 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 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 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 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 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 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 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 425 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 446 bool CvCaptureCAM_CMU::setVideoSize(int, int) 447 { 448 return false; 449 } 450 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 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 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 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 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