Home | History | Annotate | Download | only in src
      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