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 HAVE_DC1394_2 45 46 #include <unistd.h> 47 #include <stdint.h> 48 #ifdef WIN32 49 // On Windows, we have no sys/select.h, but we need to pick up 50 // select() which is in winsock2. 51 #ifndef __SYS_SELECT_H__ 52 #define __SYS_SELECT_H__ 1 53 #include <winsock2.h> 54 #endif 55 #else 56 #include <sys/select.h> 57 #endif /*WIN32*/ 58 #include <dc1394/dc1394.h> 59 #include <stdlib.h> 60 #include <string.h> 61 62 static dc1394error_t adaptBufferStereoLocal(dc1394video_frame_t *in, dc1394video_frame_t *out) 63 { 64 uint32_t bpp; 65 66 // buffer position is not changed. Size is boubled in Y 67 out->size[0] = in->size[0]; 68 out->size[1] = in->size[1] * 2; 69 out->position[0] = in->position[0]; 70 out->position[1] = in->position[1]; 71 72 // color coding is set to mono8 or raw8. 73 switch (in->color_coding) 74 { 75 case DC1394_COLOR_CODING_RAW16: 76 out->color_coding = DC1394_COLOR_CODING_RAW8; 77 break; 78 case DC1394_COLOR_CODING_MONO16: 79 case DC1394_COLOR_CODING_YUV422: 80 out->color_coding = DC1394_COLOR_CODING_MONO8; 81 break; 82 default: 83 return DC1394_INVALID_COLOR_CODING; 84 } 85 86 // keep the color filter value in all cases. if the format is not raw it will not be further used anyway 87 out->color_filter = in->color_filter; 88 89 // the output YUV byte order must be already set if the buffer is YUV422 at the output 90 // if the output is not YUV we don't care about this field. 91 // Hence nothing to do. 92 // we always convert to 8bits (at this point) we can safely set this value to 8. 93 out->data_depth = 8; 94 95 // don't know what to do with stride... >>>> TODO: STRIDE SHOULD BE TAKEN INTO ACCOUNT... <<<< 96 // out->stride=?? 97 // the video mode should not change. Color coding and other stuff can be accessed in specific fields of this struct 98 out->video_mode = in->video_mode; 99 100 // padding is kept: 101 out->padding_bytes = in->padding_bytes; 102 103 // image bytes changes: >>>> TODO: STRIDE SHOULD BE TAKEN INTO ACCOUNT... <<<< 104 dc1394_get_color_coding_bit_size(out->color_coding, &bpp); 105 out->image_bytes = (out->size[0] * out->size[1] * bpp) / 8; 106 107 // total is image_bytes + padding_bytes 108 out->total_bytes = out->image_bytes + out->padding_bytes; 109 110 // bytes-per-packet and packets_per_frame are internal data that can be kept as is. 111 out->packet_size = in->packet_size; 112 out->packets_per_frame = in->packets_per_frame; 113 114 // timestamp, frame_behind, id and camera are copied too: 115 out->timestamp = in->timestamp; 116 out->frames_behind = in->frames_behind; 117 out->camera = in->camera; 118 out->id = in->id; 119 120 // verify memory allocation: 121 if (out->total_bytes > out->allocated_image_bytes) 122 { 123 free(out->image); 124 out->image = (uint8_t*)malloc(out->total_bytes * sizeof(uint8_t)); 125 out->allocated_image_bytes = out->total_bytes; 126 } 127 128 // Copy padding bytes: 129 memcpy(&(out->image[out->image_bytes]), &(in->image[in->image_bytes]), out->padding_bytes); 130 out->little_endian = DC1394_FALSE; // not used before 1.32 is out. 131 out->data_in_padding = DC1394_FALSE; // not used before 1.32 is out. 132 return DC1394_SUCCESS; 133 } 134 135 static dc1394error_t dc1394_deinterlace_stereo_frames_fixed(dc1394video_frame_t *in, 136 dc1394video_frame_t *out, dc1394stereo_method_t method) 137 { 138 if((in->color_coding == DC1394_COLOR_CODING_RAW16) || 139 (in->color_coding == DC1394_COLOR_CODING_MONO16) || 140 (in->color_coding == DC1394_COLOR_CODING_YUV422)) 141 { 142 switch (method) 143 { 144 145 case DC1394_STEREO_METHOD_INTERLACED: 146 adaptBufferStereoLocal(in, out); 147 //FIXED by AB: 148 // dc1394_deinterlace_stereo(in->image, out->image, in->size[0], in->size[1]); 149 dc1394_deinterlace_stereo(in->image, out->image, out->size[0], out->size[1]); 150 break; 151 152 case DC1394_STEREO_METHOD_FIELD: 153 adaptBufferStereoLocal(in, out); 154 memcpy(out->image, in->image, out->image_bytes); 155 break; 156 } 157 158 return DC1394_INVALID_STEREO_METHOD; 159 } 160 else 161 return DC1394_FUNCTION_NOT_SUPPORTED; 162 } 163 164 static uint32_t getControlRegister(dc1394camera_t *camera, uint64_t offset) 165 { 166 uint32_t value = 0; 167 dc1394error_t err = dc1394_get_control_register(camera, offset, &value); 168 169 assert(err == DC1394_SUCCESS); 170 return err == DC1394_SUCCESS ? value : 0xffffffff; 171 } 172 173 struct CvDC1394 174 { 175 CvDC1394(); 176 ~CvDC1394(); 177 178 dc1394_t* dc; 179 fd_set camFds; 180 }; 181 182 CvDC1394::CvDC1394() 183 { 184 dc = dc1394_new(); 185 FD_ZERO(&camFds); 186 } 187 188 CvDC1394::~CvDC1394() 189 { 190 if (dc) 191 dc1394_free(dc); 192 dc = 0; 193 } 194 195 static CvDC1394 dc1394; 196 197 class CvCaptureCAM_DC1394_v2_CPP : public CvCapture 198 { 199 public: 200 static int dc1394properties[CV_CAP_PROP_MAX_DC1394]; 201 CvCaptureCAM_DC1394_v2_CPP(); 202 virtual ~CvCaptureCAM_DC1394_v2_CPP() 203 { 204 close(); 205 } 206 207 virtual bool open(int index); 208 virtual void close(); 209 210 virtual double getProperty(int) const; 211 virtual bool setProperty(int, double); 212 virtual bool grabFrame(); 213 virtual IplImage* retrieveFrame(int); 214 virtual int getCaptureDomain() { return CV_CAP_DC1394; } // Return the type of the capture object: CV_CAP_VFW, etc... 215 216 217 protected: 218 virtual bool startCapture(); 219 virtual bool getVidereCalibrationInfo( char* buf, int bufSize ); 220 virtual bool initVidereRectifyMaps( const char* info, IplImage* ml[2], IplImage* mr[2] ); 221 222 uint64_t guid; 223 dc1394camera_t* dcCam; 224 int isoSpeed; 225 int videoMode; 226 int frameWidth, frameHeight; 227 double fps; 228 int nDMABufs; 229 bool started; 230 int userMode; 231 232 enum { VIDERE = 0x5505 }; 233 234 int cameraId; 235 bool colorStereo; 236 dc1394bayer_method_t bayer; 237 dc1394color_filter_t bayerFilter; 238 239 enum { NIMG = 2 }; 240 IplImage *img[NIMG]; 241 dc1394video_frame_t* frameC; 242 int nimages; 243 244 bool rectify; 245 bool init_rectify; 246 IplImage *maps[NIMG][2]; 247 dc1394featureset_t feature_set; 248 }; 249 //mapping CV_CAP_PROP_ to DC1394_FEATUREs 250 int CvCaptureCAM_DC1394_v2_CPP::dc1394properties[CV_CAP_PROP_MAX_DC1394] = { 251 -1, //no corresponding feature for CV_CAP_PROP_POS_MSEC 252 -1,-1,-1,-1, 253 DC1394_FEATURE_FRAME_RATE, //CV_CAP_PROP_FPS - fps can be set for format 7 only! 254 -1,-1,-1,-1, 255 DC1394_FEATURE_BRIGHTNESS, //CV_CAP_PROP_BRIGHTNESS 10 256 -1, 257 DC1394_FEATURE_SATURATION, //CV_CAP_PROP_SATURATION 258 DC1394_FEATURE_HUE, 259 DC1394_FEATURE_GAIN, 260 DC1394_FEATURE_SHUTTER, //CV_CAP_PROP_EXPOSURE 261 -1, //CV_CAP_PROP_CONVERT_RGB 262 DC1394_FEATURE_WHITE_BALANCE, //corresponds to CV_CAP_PROP_WHITE_BALANCE_BLUE_U and CV_CAP_PROP_WHITE_BALANCE_RED_V, see set function to check these props are set 263 -1,-1, 264 DC1394_FEATURE_SHARPNESS, //20 265 DC1394_FEATURE_EXPOSURE, //CV_CAP_PROP_AUTO_EXPOSURE - this is auto exposure according to the IIDC standard 266 DC1394_FEATURE_GAMMA, //CV_CAP_PROP_GAMMA 267 DC1394_FEATURE_TEMPERATURE, //CV_CAP_PROP_TEMPERATURE 268 DC1394_FEATURE_TRIGGER, //CV_CAP_PROP_TRIGGER 269 DC1394_FEATURE_TRIGGER_DELAY, //CV_CAP_PROP_TRIGGER_DELAY 270 DC1394_FEATURE_WHITE_BALANCE, //CV_CAP_PROP_WHITE_BALANCE_RED_V 271 DC1394_FEATURE_ZOOM, //CV_CAP_PROP_ZOOM 272 DC1394_FEATURE_FOCUS, //CV_CAP_PROP_FOCUS 273 -1 //CV_CAP_PROP_GUID 274 }; 275 CvCaptureCAM_DC1394_v2_CPP::CvCaptureCAM_DC1394_v2_CPP() 276 { 277 guid = 0; 278 dcCam = 0; 279 isoSpeed = 400; 280 fps = 15; 281 // Resetted the value here to 1 in order to ensure only a single frame is stored in the buffer! 282 nDMABufs = 8; 283 started = false; 284 cameraId = 0; 285 colorStereo = false; 286 bayer = DC1394_BAYER_METHOD_BILINEAR; 287 bayerFilter = DC1394_COLOR_FILTER_GRBG; 288 frameWidth = 640; 289 frameHeight = 480; 290 291 for (int i = 0; i < NIMG; i++) 292 img[i] = maps[i][0] = maps[i][1] = 0; 293 frameC = 0; 294 nimages = 1; 295 rectify = false; 296 userMode = -1; 297 } 298 299 300 bool CvCaptureCAM_DC1394_v2_CPP::startCapture() 301 { 302 int i; 303 int code = 0; 304 if (!dcCam) 305 return false; 306 if (isoSpeed > 0) 307 { 308 // if capable set operation mode to 1394b for iso speeds above 400 309 if (isoSpeed > 400 && dcCam->bmode_capable == DC1394_TRUE) 310 { 311 dc1394_video_set_operation_mode(dcCam, DC1394_OPERATION_MODE_1394B); 312 } 313 code = dc1394_video_set_iso_speed(dcCam, 314 isoSpeed <= 100 ? DC1394_ISO_SPEED_100 : 315 isoSpeed <= 200 ? DC1394_ISO_SPEED_200 : 316 isoSpeed <= 400 ? DC1394_ISO_SPEED_400 : 317 isoSpeed <= 800 ? DC1394_ISO_SPEED_800 : 318 isoSpeed == 1600 ? DC1394_ISO_SPEED_1600 : 319 DC1394_ISO_SPEED_3200); 320 } 321 322 // should a specific mode be used 323 if (userMode >= 0) 324 325 { 326 dc1394video_mode_t wantedMode; 327 dc1394video_modes_t videoModes; 328 dc1394_video_get_supported_modes(dcCam, &videoModes); 329 330 //set mode from number, for example the second supported mode, i.e userMode = 1 331 332 if (userMode < (int)videoModes.num) 333 { 334 wantedMode = videoModes.modes[userMode]; 335 } 336 337 //set modes directly from DC134 constants (from dc1394video_mode_t) 338 else if ((userMode >= DC1394_VIDEO_MODE_MIN) && (userMode <= DC1394_VIDEO_MODE_MAX )) 339 { 340 //search for wanted mode, to check if camera supports it 341 int j = 0; 342 while ((j< (int)videoModes.num) && videoModes.modes[j]!=userMode) 343 { 344 j++; 345 } 346 347 if ((int)videoModes.modes[j]==userMode) 348 { 349 wantedMode = videoModes.modes[j]; 350 } 351 else 352 { 353 userMode = -1; // wanted mode not supported, search for best mode 354 } 355 } 356 else 357 { 358 userMode = -1; // wanted mode not supported, search for best mode 359 } 360 //if userMode is available: set it and update size 361 if (userMode != -1) 362 { 363 code = dc1394_video_set_mode(dcCam, wantedMode); 364 uint32_t width, height; 365 dc1394_get_image_size_from_video_mode(dcCam, wantedMode, &width, &height); 366 frameWidth = (int)width; 367 frameHeight = (int)height; 368 } 369 } 370 371 if (userMode == -1 && (frameWidth > 0 || frameHeight > 0)) 372 { 373 dc1394video_mode_t bestMode = (dc1394video_mode_t) - 1; 374 dc1394video_modes_t videoModes; 375 dc1394_video_get_supported_modes(dcCam, &videoModes); 376 for (i = 0; i < (int)videoModes.num; i++) 377 { 378 dc1394video_mode_t mode = videoModes.modes[i]; 379 if (mode >= DC1394_VIDEO_MODE_FORMAT7_MIN && mode <= DC1394_VIDEO_MODE_FORMAT7_MAX) 380 continue; 381 int pref = -1; 382 dc1394color_coding_t colorCoding; 383 dc1394_get_color_coding_from_video_mode(dcCam, mode, &colorCoding); 384 385 uint32_t width, height; 386 dc1394_get_image_size_from_video_mode(dcCam, mode, &width, &height); 387 if ((int)width == frameWidth || (int)height == frameHeight) 388 { 389 if (colorCoding == DC1394_COLOR_CODING_RGB8 || 390 colorCoding == DC1394_COLOR_CODING_RAW8) 391 { 392 bestMode = mode; 393 break; 394 } 395 396 if (colorCoding == DC1394_COLOR_CODING_YUV411 || 397 colorCoding == DC1394_COLOR_CODING_YUV422 || 398 (colorCoding == DC1394_COLOR_CODING_YUV444 && 399 pref < 1)) 400 { 401 bestMode = mode; 402 pref = 1; 403 break; 404 } 405 406 if (colorCoding == DC1394_COLOR_CODING_MONO8) 407 { 408 bestMode = mode; 409 pref = 0; 410 } 411 } 412 } 413 if ((int)bestMode >= 0) 414 code = dc1394_video_set_mode(dcCam, bestMode); 415 } 416 417 if (fps > 0) 418 { 419 dc1394video_mode_t mode; 420 dc1394framerates_t framerates; 421 double minDiff = DBL_MAX; 422 dc1394framerate_t bestFps = (dc1394framerate_t) - 1; 423 424 dc1394_video_get_mode(dcCam, &mode); 425 dc1394_video_get_supported_framerates(dcCam, mode, &framerates); 426 427 for (i = 0; i < (int)framerates.num; i++) 428 { 429 dc1394framerate_t ifps = framerates.framerates[i]; 430 double fps1 = (1 << (ifps - DC1394_FRAMERATE_1_875)) * 1.875; 431 double diff = fabs(fps1 - fps); 432 if (diff < minDiff) 433 { 434 minDiff = diff; 435 bestFps = ifps; 436 } 437 } 438 if ((int)bestFps >= 0) 439 code = dc1394_video_set_framerate(dcCam, bestFps); 440 } 441 442 if (cameraId == VIDERE) 443 { 444 bayerFilter = DC1394_COLOR_FILTER_GBRG; 445 nimages = 2; 446 uint32_t value = 0; 447 dc1394_get_control_register(dcCam, 0x50c, &value); 448 colorStereo = (value & 0x80000000) != 0; 449 } 450 451 code = dc1394_capture_setup(dcCam, nDMABufs, DC1394_CAPTURE_FLAGS_DEFAULT); 452 if (code >= 0) 453 { 454 FD_SET(dc1394_capture_get_fileno(dcCam), &dc1394.camFds); 455 dc1394_video_set_transmission(dcCam, DC1394_ON); 456 if (cameraId == VIDERE) 457 { 458 enum { PROC_MODE_OFF, PROC_MODE_NONE, PROC_MODE_TEST, PROC_MODE_RECTIFIED, PROC_MODE_DISPARITY, PROC_MODE_DISPARITY_RAW }; 459 int procMode = PROC_MODE_RECTIFIED; 460 usleep(100000); 461 uint32_t qval1 = 0x08000000 | (0x90 << 16) | ((procMode & 0x7) << 16); 462 uint32_t qval2 = 0x08000000 | (0x9C << 16); 463 dc1394_set_control_register(dcCam, 0xFF000, qval1); 464 dc1394_set_control_register(dcCam, 0xFF000, qval2); 465 } 466 started = true; 467 } 468 469 return code >= 0; 470 } 471 472 bool CvCaptureCAM_DC1394_v2_CPP::open(int index) 473 { 474 bool result = false; 475 dc1394camera_list_t* cameraList = 0; 476 dc1394error_t err; 477 478 close(); 479 480 if (!dc1394.dc) 481 goto _exit_; 482 483 err = dc1394_camera_enumerate(dc1394.dc, &cameraList); 484 if (err < 0 || !cameraList || (unsigned)index >= (unsigned)cameraList->num) 485 goto _exit_; 486 487 guid = cameraList->ids[index].guid; 488 dcCam = dc1394_camera_new(dc1394.dc, guid); 489 if (!dcCam) 490 goto _exit_; 491 492 cameraId = dcCam->vendor_id; 493 //get all features 494 if (dc1394_feature_get_all(dcCam,&feature_set) == DC1394_SUCCESS) 495 result = true; 496 else 497 result = false; 498 499 _exit_: 500 if (cameraList) 501 dc1394_camera_free_list(cameraList); 502 503 return result; 504 } 505 506 void CvCaptureCAM_DC1394_v2_CPP::close() 507 { 508 if (dcCam) 509 { 510 // check for fileno valid before using 511 int fileno=dc1394_capture_get_fileno(dcCam); 512 513 if (fileno>=0 && FD_ISSET(fileno, &dc1394.camFds)) 514 FD_CLR(fileno, &dc1394.camFds); 515 dc1394_video_set_transmission(dcCam, DC1394_OFF); 516 dc1394_capture_stop(dcCam); 517 dc1394_camera_free(dcCam); 518 dcCam = 0; 519 started = false; 520 } 521 522 for (int i = 0; i < NIMG; i++) 523 { 524 cvReleaseImage(&img[i]); 525 cvReleaseImage(&maps[i][0]); 526 cvReleaseImage(&maps[i][1]); 527 } 528 if (frameC) 529 { 530 if (frameC->image) 531 free(frameC->image); 532 free(frameC); 533 frameC = 0; 534 } 535 } 536 537 538 bool CvCaptureCAM_DC1394_v2_CPP::grabFrame() 539 { 540 dc1394capture_policy_t policy = DC1394_CAPTURE_POLICY_WAIT; 541 bool code = false, isColor; 542 dc1394video_frame_t *dcFrame = 0, *fs = 0; 543 int i, nch; 544 545 if (!dcCam || (!started && !startCapture())) 546 return false; 547 548 dc1394_capture_dequeue(dcCam, policy, &dcFrame); 549 550 if (!dcFrame) 551 return false; 552 553 if (/*dcFrame->frames_behind > 1 ||*/ dc1394_capture_is_frame_corrupt(dcCam, dcFrame) == DC1394_TRUE) 554 { 555 goto _exit_; 556 } 557 558 isColor = dcFrame->color_coding != DC1394_COLOR_CODING_MONO8 && 559 dcFrame->color_coding != DC1394_COLOR_CODING_MONO16 && 560 dcFrame->color_coding != DC1394_COLOR_CODING_MONO16S; 561 562 if (nimages == 2) 563 { 564 fs = (dc1394video_frame_t*)calloc(1, sizeof(*fs)); 565 566 //dc1394_deinterlace_stereo_frames(dcFrame, fs, DC1394_STEREO_METHOD_INTERLACED); 567 dc1394_deinterlace_stereo_frames_fixed(dcFrame, fs, DC1394_STEREO_METHOD_INTERLACED); 568 569 dc1394_capture_enqueue(dcCam, dcFrame); // release the captured frame as soon as possible 570 dcFrame = 0; 571 if (!fs->image) 572 goto _exit_; 573 isColor = colorStereo; 574 } 575 nch = isColor ? 3 : 1; 576 577 for (i = 0; i < nimages; i++) 578 { 579 IplImage fhdr; 580 dc1394video_frame_t f = fs ? *fs : *dcFrame, *fc = &f; 581 f.size[1] /= nimages; 582 f.image += f.size[0] * f.size[1] * i; // TODO: make it more universal 583 if (isColor) 584 { 585 if (!frameC) 586 frameC = (dc1394video_frame_t*)calloc(1, sizeof(*frameC)); 587 frameC->color_coding = nch == 3 ? DC1394_COLOR_CODING_RGB8 : DC1394_COLOR_CODING_MONO8; 588 if (nimages == 1) 589 { 590 dc1394_convert_frames(&f, frameC); 591 dc1394_capture_enqueue(dcCam, dcFrame); 592 dcFrame = 0; 593 } 594 else 595 { 596 f.color_filter = bayerFilter; 597 dc1394_debayer_frames(&f, frameC, bayer); 598 } 599 fc = frameC; 600 } 601 if (!img[i]) 602 img[i] = cvCreateImage(cvSize(fc->size[0], fc->size[1]), 8, nch); 603 cvInitImageHeader(&fhdr, cvSize(fc->size[0], fc->size[1]), 8, nch); 604 cvSetData(&fhdr, fc->image, fc->size[0]*nch); 605 606 // Swap R&B channels: 607 if (nch==3) 608 cvConvertImage(&fhdr,&fhdr,CV_CVTIMG_SWAP_RB); 609 610 if( rectify && cameraId == VIDERE && nimages == 2 ) 611 { 612 if( !maps[0][0] || maps[0][0]->width != img[i]->width || maps[0][0]->height != img[i]->height ) 613 { 614 CvSize size = cvGetSize(img[i]); 615 cvReleaseImage(&maps[0][0]); 616 cvReleaseImage(&maps[0][1]); 617 cvReleaseImage(&maps[1][0]); 618 cvReleaseImage(&maps[1][1]); 619 maps[0][0] = cvCreateImage(size, IPL_DEPTH_16S, 2); 620 maps[0][1] = cvCreateImage(size, IPL_DEPTH_16S, 1); 621 maps[1][0] = cvCreateImage(size, IPL_DEPTH_16S, 2); 622 maps[1][1] = cvCreateImage(size, IPL_DEPTH_16S, 1); 623 char buf[4*4096]; 624 if( getVidereCalibrationInfo( buf, (int)sizeof(buf) ) && 625 initVidereRectifyMaps( buf, maps[0], maps[1] )) 626 ; 627 else 628 rectify = false; 629 } 630 cvRemap(&fhdr, img[i], maps[i][0], maps[i][1]); 631 } 632 else 633 cvCopy(&fhdr, img[i]); 634 } 635 636 code = true; 637 638 _exit_: 639 if (dcFrame) 640 dc1394_capture_enqueue(dcCam, dcFrame); 641 if (fs) 642 { 643 if (fs->image) 644 free(fs->image); 645 free(fs); 646 } 647 648 return code; 649 } 650 651 IplImage* CvCaptureCAM_DC1394_v2_CPP::retrieveFrame(int idx) 652 { 653 return 0 <= idx && idx < nimages ? img[idx] : 0; 654 } 655 656 double CvCaptureCAM_DC1394_v2_CPP::getProperty(int propId) const 657 { 658 // Simulate mutable (C++11-like) member variable 659 dc1394featureset_t& fs = const_cast<dc1394featureset_t&>(feature_set); 660 661 switch (propId) 662 { 663 case CV_CAP_PROP_FRAME_WIDTH: 664 return frameWidth ? frameWidth : frameHeight*4 / 3; 665 case CV_CAP_PROP_FRAME_HEIGHT: 666 return frameHeight ? frameHeight : frameWidth*3 / 4; 667 case CV_CAP_PROP_FPS: 668 return fps; 669 case CV_CAP_PROP_RECTIFICATION: 670 return rectify ? 1 : 0; 671 case CV_CAP_PROP_WHITE_BALANCE_BLUE_U: 672 if (dc1394_feature_whitebalance_get_value(dcCam, 673 &fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value, 674 &fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value) == DC1394_SUCCESS) 675 return feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value; 676 break; 677 case CV_CAP_PROP_WHITE_BALANCE_RED_V: 678 if (dc1394_feature_whitebalance_get_value(dcCam, 679 &fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].BU_value, 680 &fs.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value) == DC1394_SUCCESS) 681 return feature_set.feature[DC1394_FEATURE_WHITE_BALANCE-DC1394_FEATURE_MIN].RV_value; 682 break; 683 case CV_CAP_PROP_GUID: 684 //the least 32 bits are enough to identify the camera 685 return (double) (guid & 0x00000000FFFFFFFF); 686 break; 687 case CV_CAP_PROP_MODE: 688 return (double) userMode; 689 break; 690 case CV_CAP_PROP_ISO_SPEED: 691 return (double) isoSpeed; 692 case CV_CAP_PROP_BUFFERSIZE: 693 return (double) nDMABufs; 694 default: 695 if (propId<CV_CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1 696 && dcCam) 697 //&& feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].on_off_capable) 698 if (dc1394_feature_get_value(dcCam,(dc1394feature_t)dc1394properties[propId], 699 &fs.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].value) == DC1394_SUCCESS) 700 return feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].value; 701 } 702 return -1; // the value of the feature can be 0, so returning 0 as an error is wrong 703 } 704 705 bool CvCaptureCAM_DC1394_v2_CPP::setProperty(int propId, double value) 706 { 707 switch (propId) 708 { 709 case CV_CAP_PROP_FRAME_WIDTH: 710 if(started) 711 return false; 712 frameWidth = cvRound(value); 713 frameHeight = 0; 714 break; 715 case CV_CAP_PROP_FRAME_HEIGHT: 716 if(started) 717 return false; 718 frameWidth = 0; 719 frameHeight = cvRound(value); 720 break; 721 case CV_CAP_PROP_FPS: 722 if(started) 723 return false; 724 fps = value; 725 break; 726 case CV_CAP_PROP_RECTIFICATION: 727 if( cameraId != VIDERE ) 728 return false; 729 rectify = fabs(value) > FLT_EPSILON; 730 break; 731 case CV_CAP_PROP_MODE: 732 if(started) 733 return false; 734 userMode = cvRound(value); 735 break; 736 case CV_CAP_PROP_ISO_SPEED: 737 if(started) 738 return false; 739 isoSpeed = cvRound(value); 740 break; 741 case CV_CAP_PROP_BUFFERSIZE: 742 if(started) 743 return false; 744 nDMABufs = value; 745 break; 746 //The code below is based on coriander, callbacks.c:795, refer to case RANGE_MENU_MAN : 747 default: 748 if (propId<CV_CAP_PROP_MAX_DC1394 && dc1394properties[propId]!=-1 749 && dcCam) 750 { 751 //get the corresponding feature from property-id 752 dc1394feature_info_t *act_feature = &feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN]; 753 754 if (cvRound(value) == CV_CAP_PROP_DC1394_OFF) 755 { 756 if ( (act_feature->on_off_capable) 757 && (dc1394_feature_set_power(dcCam, act_feature->id, DC1394_OFF) == DC1394_SUCCESS)) 758 { 759 act_feature->is_on=DC1394_OFF; 760 return true; 761 } 762 return false; 763 } 764 //try to turn the feature ON, feature can be ON and at the same time it can be not capable to change state to OFF 765 if ( (act_feature->is_on == DC1394_OFF) && (act_feature->on_off_capable == DC1394_TRUE)) 766 { 767 if (dc1394_feature_set_power(dcCam, act_feature->id, DC1394_ON) == DC1394_SUCCESS) 768 feature_set.feature[dc1394properties[propId]-DC1394_FEATURE_MIN].is_on=DC1394_ON; 769 } 770 //turn off absolute mode - the actual value will be stored in the value field, 771 //otherwise it would be stored into CSR (control and status register) absolute value 772 if (act_feature->absolute_capable 773 && dc1394_feature_set_absolute_control(dcCam, act_feature->id, DC1394_OFF) !=DC1394_SUCCESS) 774 return false; 775 else 776 act_feature->abs_control=DC1394_OFF; 777 //set AUTO 778 if (cvRound(value) == CV_CAP_PROP_DC1394_MODE_AUTO) 779 { 780 if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_AUTO)!=DC1394_SUCCESS) 781 return false; 782 act_feature->current_mode=DC1394_FEATURE_MODE_AUTO; 783 return true; 784 } 785 //set ONE PUSH 786 if (cvRound(value) == CV_CAP_PROP_DC1394_MODE_ONE_PUSH_AUTO) 787 { 788 //have to set to manual first, otherwise one push will be ignored (AVT manual 4.3.0 p. 115) 789 if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_ONE_PUSH_AUTO)!=DC1394_SUCCESS) 790 return false; 791 //will change to 792 act_feature->current_mode=DC1394_FEATURE_MODE_ONE_PUSH_AUTO; 793 return true; 794 } 795 //set the feature to MANUAL mode, 796 if (dc1394_feature_set_mode(dcCam, act_feature->id, DC1394_FEATURE_MODE_MANUAL)!=DC1394_SUCCESS) 797 return false; 798 else 799 act_feature->current_mode=DC1394_FEATURE_MODE_MANUAL; 800 // if property is one of the white balance features treat it in different way 801 if (propId == CV_CAP_PROP_WHITE_BALANCE_BLUE_U) 802 { 803 if (dc1394_feature_whitebalance_set_value(dcCam,cvRound(value), act_feature->RV_value)!=DC1394_SUCCESS) 804 return false; 805 else 806 { 807 act_feature->BU_value = cvRound(value); 808 return true; 809 } 810 } 811 if (propId == CV_CAP_PROP_WHITE_BALANCE_RED_V) 812 { 813 if (dc1394_feature_whitebalance_set_value(dcCam, act_feature->BU_value, cvRound(value))!=DC1394_SUCCESS) 814 return false; 815 else 816 { 817 act_feature->RV_value = cvRound(value); 818 return true; 819 } 820 } 821 822 //first: check boundaries 823 if (value < act_feature->min) 824 { 825 value = act_feature->min; 826 } 827 else if (value > act_feature->max) 828 { 829 value = act_feature->max; 830 } 831 832 if (dc1394_feature_set_value(dcCam, act_feature->id, cvRound(value)) == DC1394_SUCCESS) 833 { 834 act_feature->value = value; 835 return true; 836 } 837 } 838 return false; 839 } 840 return true; 841 } 842 843 844 bool CvCaptureCAM_DC1394_v2_CPP::getVidereCalibrationInfo( char* buf, int bufSize ) 845 { 846 int pos; 847 848 for( pos = 0; pos < bufSize - 4; pos += 4 ) 849 { 850 uint32_t quad = getControlRegister(dcCam, 0xF0800 + pos); 851 if( quad == 0 || quad == 0xffffffff ) 852 break; 853 buf[pos] = (uchar)(quad >> 24); 854 buf[pos+1] = (uchar)(quad >> 16); 855 buf[pos+2] = (uchar)(quad >> 8); 856 buf[pos+3] = (uchar)(quad); 857 } 858 859 if( pos == 0 ) 860 return false; 861 862 buf[pos] = '\0'; 863 return true; 864 } 865 866 867 bool CvCaptureCAM_DC1394_v2_CPP::initVidereRectifyMaps( const char* info, 868 IplImage* ml[2], IplImage* mr[2] ) 869 { 870 float identity_data[] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; 871 CvMat l_rect = cvMat(3, 3, CV_32F, identity_data), r_rect = l_rect; 872 float l_intrinsic_data[] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; 873 float r_intrinsic_data[] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; 874 CvMat l_intrinsic = cvMat(3, 3, CV_32F, l_intrinsic_data); 875 CvMat r_intrinsic = cvMat(3, 3, CV_32F, r_intrinsic_data); 876 float l_distortion_data[] = {0,0,0,0,0}, r_distortion_data[] = {0,0,0,0,0}; 877 CvMat l_distortion = cvMat(1, 5, CV_32F, l_distortion_data); 878 CvMat r_distortion = cvMat(1, 5, CV_32F, r_distortion_data); 879 IplImage* mx = cvCreateImage(cvGetSize(ml[0]), IPL_DEPTH_32F, 1); 880 IplImage* my = cvCreateImage(cvGetSize(ml[0]), IPL_DEPTH_32F, 1); 881 int k, j; 882 883 for( k = 0; k < 2; k++ ) 884 { 885 const char* section_name = k == 0 ? "[left_camera]" : "[right_camera]"; 886 static const char* param_names[] = { "f ", "fy", "Cx", "Cy" "kappa1", "kappa2", "tau1", "tau2", "kappa3", 0 }; 887 const char* section_start = strstr( info, section_name ); 888 CvMat* intrinsic = k == 0 ? &l_intrinsic : &r_intrinsic; 889 CvMat* distortion = k == 0 ? &l_distortion : &r_distortion; 890 CvMat* rectification = k == 0 ? &l_rect : &r_rect; 891 IplImage** dst = k == 0 ? ml : mr; 892 if( !section_start ) 893 break; 894 section_start += strlen(section_name); 895 for( j = 0; param_names[j] != 0; j++ ) 896 { 897 const char* param_value_start = strstr(section_start, param_names[j]); 898 float val=0; 899 if(!param_value_start) 900 break; 901 sscanf(param_value_start + strlen(param_names[j]), "%f", &val); 902 if( j < 4 ) 903 intrinsic->data.fl[j == 0 ? 0 : j == 1 ? 4 : j == 2 ? 2 : 5] = val; 904 else 905 distortion->data.fl[j - 4] = val; 906 } 907 if( param_names[j] != 0 ) 908 break; 909 910 // some sanity check for the principal point 911 if( fabs(mx->width*0.5 - intrinsic->data.fl[2]) > mx->width*0.1 || 912 fabs(my->height*0.5 - intrinsic->data.fl[5]) > my->height*0.1 ) 913 { 914 cvScale( &intrinsic, &intrinsic, 0.5 ); // try the corrected intrinsic matrix for 2x lower resolution 915 if( fabs(mx->width*0.5 - intrinsic->data.fl[2]) > mx->width*0.05 || 916 fabs(my->height*0.5 - intrinsic->data.fl[5]) > my->height*0.05 ) 917 cvScale( &intrinsic, &intrinsic, 2 ); // revert it back if the new variant is not much better 918 intrinsic->data.fl[8] = 1; 919 } 920 921 cvInitUndistortRectifyMap( intrinsic, distortion, 922 rectification, intrinsic, mx, my ); 923 cvConvertMaps( mx, my, dst[0], dst[1] ); 924 } 925 926 cvReleaseImage( &mx ); 927 cvReleaseImage( &my ); 928 return k >= 2; 929 } 930 931 932 CvCapture* cvCreateCameraCapture_DC1394_2(int index) 933 { 934 CvCaptureCAM_DC1394_v2_CPP* capture = new CvCaptureCAM_DC1394_v2_CPP; 935 936 if (capture->open(index)) 937 return capture; 938 939 delete capture; 940 return 0; 941 } 942 943 #endif 944