1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
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.
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.
48 #include <sys/select.h>
49 #include <dc1394/dc1394.h>
54 static dc1394error_t adaptBufferStereoLocal(dc1394video_frame_t *in, dc1394video_frame_t *out)
58 // buffer position is not changed. Size is boubled in Y
59 out->size[0] = in->size[0];
60 out->size[1] = in->size[1] * 2;
61 out->position[0] = in->position[0];
62 out->position[1] = in->position[1];
64 // color coding is set to mono8 or raw8.
65 switch (in->color_coding)
67 case DC1394_COLOR_CODING_RAW16:
68 out->color_coding = DC1394_COLOR_CODING_RAW8;
70 case DC1394_COLOR_CODING_MONO16:
71 case DC1394_COLOR_CODING_YUV422:
72 out->color_coding = DC1394_COLOR_CODING_MONO8;
75 return DC1394_INVALID_COLOR_CODING;
78 // keep the color filter value in all cases. if the format is not raw it will not be further used anyway
79 out->color_filter = in->color_filter;
81 // the output YUV byte order must be already set if the buffer is YUV422 at the output
82 // if the output is not YUV we don't care about this field.
83 // Hence nothing to do.
84 // we always convert to 8bits (at this point) we can safely set this value to 8.
87 // don't know what to do with stride... >>>> TODO: STRIDE SHOULD BE TAKEN INTO ACCOUNT... <<<<
89 // the video mode should not change. Color coding and other stuff can be accessed in specific fields of this struct
90 out->video_mode = in->video_mode;
93 out->padding_bytes = in->padding_bytes;
95 // image bytes changes: >>>> TODO: STRIDE SHOULD BE TAKEN INTO ACCOUNT... <<<<
96 dc1394_get_color_coding_bit_size(out->color_coding, &bpp);
97 out->image_bytes = (out->size[0] * out->size[1] * bpp) / 8;
99 // total is image_bytes + padding_bytes
100 out->total_bytes = out->image_bytes + out->padding_bytes;
102 // bytes-per-packet and packets_per_frame are internal data that can be kept as is.
103 out->packet_size = in->packet_size;
104 out->packets_per_frame = in->packets_per_frame;
106 // timestamp, frame_behind, id and camera are copied too:
107 out->timestamp = in->timestamp;
108 out->frames_behind = in->frames_behind;
109 out->camera = in->camera;
112 // verify memory allocation:
113 if (out->total_bytes > out->allocated_image_bytes)
116 out->image = (uint8_t*)malloc(out->total_bytes * sizeof(uint8_t));
117 out->allocated_image_bytes = out->total_bytes;
120 // Copy padding bytes:
121 memcpy(&(out->image[out->image_bytes]), &(in->image[in->image_bytes]), out->padding_bytes);
122 out->little_endian = DC1394_FALSE; // not used before 1.32 is out.
123 out->data_in_padding = DC1394_FALSE; // not used before 1.32 is out.
124 return DC1394_SUCCESS;
127 static dc1394error_t dc1394_deinterlace_stereo_frames_fixed(dc1394video_frame_t *in,
128 dc1394video_frame_t *out, dc1394stereo_method_t method)
132 if((in->color_coding == DC1394_COLOR_CODING_RAW16) ||
133 (in->color_coding == DC1394_COLOR_CODING_MONO16) ||
134 (in->color_coding == DC1394_COLOR_CODING_YUV422))
139 case DC1394_STEREO_METHOD_INTERLACED:
140 err = adaptBufferStereoLocal(in, out);
142 // dc1394_deinterlace_stereo(in->image, out->image, in->size[0], in->size[1]);
143 dc1394_deinterlace_stereo(in->image, out->image, out->size[0], out->size[1]);
146 case DC1394_STEREO_METHOD_FIELD:
147 err = adaptBufferStereoLocal(in, out);
148 memcpy(out->image, in->image, out->image_bytes);
152 return DC1394_INVALID_STEREO_METHOD;
155 return DC1394_FUNCTION_NOT_SUPPORTED;
158 static uint32_t getControlRegister(dc1394camera_t *camera, uint64_t offset)
161 dc1394error_t err = dc1394_get_control_register(camera, offset, &value);
163 assert(err == DC1394_SUCCESS);
164 return err == DC1394_SUCCESS ? value : 0xffffffff;
182 CvDC1394::~CvDC1394()
189 static CvDC1394 dc1394;
191 class CvCaptureCAM_DC1394_v2_CPP : public CvCapture
194 CvCaptureCAM_DC1394_v2_CPP();
195 virtual ~CvCaptureCAM_DC1394_v2_CPP()
200 virtual bool open(int index);
201 virtual void close();
203 virtual double getProperty(int);
204 virtual bool setProperty(int, double);
205 virtual bool grabFrame();
206 virtual IplImage* retrieveFrame(int);
207 virtual int getCaptureDomain() { return CV_CAP_DC1394; } // Return the type of the capture object: CV_CAP_VFW, etc...
211 virtual bool startCapture();
212 virtual bool getVidereCalibrationInfo( char* buf, int bufSize );
213 virtual bool initVidereRectifyMaps( const char* info, IplImage* ml[2], IplImage* mr[2] );
216 dc1394camera_t* dcCam;
219 int frameWidth, frameHeight;
224 enum { VIDERE = 0x5505 };
228 dc1394bayer_method_t bayer;
229 dc1394color_filter_t bayerFilter;
233 dc1394video_frame_t* frameC;
238 IplImage *maps[NIMG][2];
241 CvCaptureCAM_DC1394_v2_CPP::CvCaptureCAM_DC1394_v2_CPP()
251 bayer = DC1394_BAYER_METHOD_BILINEAR;
252 bayerFilter = DC1394_COLOR_FILTER_GRBG;
256 for (int i = 0; i < NIMG; i++)
257 img[i] = maps[i][0] = maps[i][1] = 0;
264 bool CvCaptureCAM_DC1394_v2_CPP::startCapture()
272 code = dc1394_video_set_iso_speed(dcCam,
273 isoSpeed <= 100 ? DC1394_ISO_SPEED_100 :
274 isoSpeed <= 200 ? DC1394_ISO_SPEED_200 :
275 isoSpeed <= 400 ? DC1394_ISO_SPEED_400 :
276 isoSpeed <= 800 ? DC1394_ISO_SPEED_800 :
277 isoSpeed == 1600 ? DC1394_ISO_SPEED_1600 :
278 DC1394_ISO_SPEED_3200);
281 if (frameWidth > 0 || frameHeight > 0)
283 dc1394video_mode_t bestMode = (dc1394video_mode_t) - 1;
284 dc1394video_modes_t videoModes;
285 dc1394_video_get_supported_modes(dcCam, &videoModes);
286 for (i = 0; i < (int)videoModes.num; i++)
288 dc1394video_mode_t mode = videoModes.modes[i];
289 if (mode >= DC1394_VIDEO_MODE_FORMAT7_MIN && mode <= DC1394_VIDEO_MODE_FORMAT7_MAX)
292 dc1394color_coding_t colorCoding;
293 dc1394_get_color_coding_from_video_mode(dcCam, mode, &colorCoding);
295 uint32_t width, height;
296 dc1394_get_image_size_from_video_mode(dcCam, mode, &width, &height);
297 if ((int)width == frameWidth || (int)height == frameHeight)
299 if (colorCoding == DC1394_COLOR_CODING_RGB8 ||
300 colorCoding == DC1394_COLOR_CODING_RGB16 ||
301 colorCoding == DC1394_COLOR_CODING_RAW8 ||
302 colorCoding == DC1394_COLOR_CODING_RAW16)
308 if (colorCoding == DC1394_COLOR_CODING_YUV411 ||
309 colorCoding == DC1394_COLOR_CODING_YUV422 ||
310 (colorCoding == DC1394_COLOR_CODING_YUV444 &&
317 if (colorCoding == DC1394_COLOR_CODING_MONO8 ||
318 (colorCoding == DC1394_COLOR_CODING_MONO16 &&
326 if ((int)bestMode >= 0)
327 code = dc1394_video_set_mode(dcCam, bestMode);
332 dc1394video_mode_t mode;
333 dc1394framerates_t framerates;
334 double minDiff = DBL_MAX;
335 dc1394framerate_t bestFps = (dc1394framerate_t) - 1;
337 dc1394_video_get_mode(dcCam, &mode);
338 dc1394_video_get_supported_framerates(dcCam, mode, &framerates);
340 for (i = 0; i < (int)framerates.num; i++)
342 dc1394framerate_t ifps = framerates.framerates[i];
343 double fps1 = (1 << (ifps - DC1394_FRAMERATE_1_875)) * 1.875;
344 double diff = fabs(fps1 - fps);
351 if ((int)bestFps >= 0)
352 code = dc1394_video_set_framerate(dcCam, bestFps);
355 if (cameraId == VIDERE)
357 bayerFilter = DC1394_COLOR_FILTER_GBRG;
360 dc1394_get_control_register(dcCam, 0x50c, &value);
361 colorStereo = (value & 0x80000000) != 0;
364 code = dc1394_capture_setup(dcCam, nDMABufs, DC1394_CAPTURE_FLAGS_DEFAULT);
367 FD_SET(dc1394_capture_get_fileno(dcCam), &dc1394.camFds);
368 dc1394_video_set_transmission(dcCam, DC1394_ON);
369 if (cameraId == VIDERE)
371 enum { PROC_MODE_OFF, PROC_MODE_NONE, PROC_MODE_TEST, PROC_MODE_RECTIFIED, PROC_MODE_DISPARITY, PROC_MODE_DISPARITY_RAW };
372 int procMode = PROC_MODE_RECTIFIED;
374 uint32_t qval1 = 0x08000000 | (0x90 << 16) | ((procMode & 0x7) << 16);
375 uint32_t qval2 = 0x08000000 | (0x9C << 16);
376 dc1394_set_control_register(dcCam, 0xFF000, qval1);
377 dc1394_set_control_register(dcCam, 0xFF000, qval2);
385 bool CvCaptureCAM_DC1394_v2_CPP::open(int index)
388 dc1394camera_list_t* cameraList = 0;
396 err = dc1394_camera_enumerate(dc1394.dc, &cameraList);
397 if (err < 0 || !cameraList || (unsigned)index >= (unsigned)cameraList->num)
400 guid = cameraList->ids[index].guid;
401 dcCam = dc1394_camera_new(dc1394.dc, guid);
405 cameraId = dcCam->vendor_id;
410 dc1394_camera_free_list(cameraList);
415 void CvCaptureCAM_DC1394_v2_CPP::close()
419 if (FD_ISSET(dc1394_capture_get_fileno(dcCam), &dc1394.camFds))
420 FD_CLR(dc1394_capture_get_fileno(dcCam), &dc1394.camFds);
421 dc1394_video_set_transmission(dcCam, DC1394_OFF);
422 dc1394_capture_stop(dcCam);
423 dc1394_camera_free(dcCam);
428 for (int i = 0; i < NIMG; i++)
430 cvReleaseImage(&img[i]);
431 cvReleaseImage(&maps[i][0]);
432 cvReleaseImage(&maps[i][1]);
444 bool CvCaptureCAM_DC1394_v2_CPP::grabFrame()
446 dc1394capture_policy_t policy = DC1394_CAPTURE_POLICY_WAIT;
447 bool code = false, isColor;
448 dc1394video_frame_t *dcFrame = 0, *fs = 0;
451 if (!dcCam || (!started && !startCapture()))
454 dc1394_capture_dequeue(dcCam, policy, &dcFrame);
459 if (/*dcFrame->frames_behind > 1 ||*/ dc1394_capture_is_frame_corrupt(dcCam, dcFrame) == DC1394_TRUE)
464 isColor = dcFrame->color_coding != DC1394_COLOR_CODING_MONO8 &&
465 dcFrame->color_coding != DC1394_COLOR_CODING_MONO16 &&
466 dcFrame->color_coding != DC1394_COLOR_CODING_MONO16S;
470 fs = (dc1394video_frame_t*)calloc(1, sizeof(*fs));
472 //dc1394_deinterlace_stereo_frames(dcFrame, fs, DC1394_STEREO_METHOD_INTERLACED);
473 dc1394_deinterlace_stereo_frames_fixed(dcFrame, fs, DC1394_STEREO_METHOD_INTERLACED);
475 dc1394_capture_enqueue(dcCam, dcFrame); // release the captured frame as soon as possible
479 isColor = colorStereo;
481 nch = isColor ? 3 : 1;
483 for (i = 0; i < nimages; i++)
486 dc1394video_frame_t f = fs ? *fs : *dcFrame, *fc = &f;
487 f.size[1] /= nimages;
488 f.image += f.size[0] * f.size[1] * i; // TODO: make it more universal
492 frameC = (dc1394video_frame_t*)calloc(1, sizeof(*frameC));
493 frameC->color_coding = nch == 3 ? DC1394_COLOR_CODING_RGB8 : DC1394_COLOR_CODING_MONO8;
496 dc1394_convert_frames(&f, frameC);
497 dc1394_capture_enqueue(dcCam, dcFrame);
502 f.color_filter = bayerFilter;
503 dc1394_debayer_frames(&f, frameC, bayer);
508 img[i] = cvCreateImage(cvSize(fc->size[0], fc->size[1]), 8, nch);
509 cvInitImageHeader(&fhdr, cvSize(fc->size[0], fc->size[1]), 8, nch);
510 cvSetData(&fhdr, fc->image, fc->size[0]*nch);
512 // Swap R&B channels:
514 cvConvertImage(&fhdr,&fhdr,CV_CVTIMG_SWAP_RB);
516 if( rectify && cameraId == VIDERE && nimages == 2 )
518 if( !maps[0][0] || maps[0][0]->width != img[i]->width || maps[0][0]->height != img[i]->height )
520 CvSize size = cvGetSize(img[i]);
521 cvReleaseImage(&maps[0][0]);
522 cvReleaseImage(&maps[0][1]);
523 cvReleaseImage(&maps[1][0]);
524 cvReleaseImage(&maps[1][1]);
525 maps[0][0] = cvCreateImage(size, IPL_DEPTH_16S, 2);
526 maps[0][1] = cvCreateImage(size, IPL_DEPTH_16S, 1);
527 maps[1][0] = cvCreateImage(size, IPL_DEPTH_16S, 2);
528 maps[1][1] = cvCreateImage(size, IPL_DEPTH_16S, 1);
530 if( getVidereCalibrationInfo( buf, (int)sizeof(buf) ) &&
531 initVidereRectifyMaps( buf, maps[0], maps[1] ))
536 cvRemap(&fhdr, img[i], maps[i][0], maps[i][1]);
539 cvCopy(&fhdr, img[i]);
546 dc1394_capture_enqueue(dcCam, dcFrame);
557 IplImage* CvCaptureCAM_DC1394_v2_CPP::retrieveFrame(int idx)
559 return 0 <= idx && idx < nimages ? img[idx] : 0;
562 double CvCaptureCAM_DC1394_v2_CPP::getProperty(int propId)
566 case CV_CAP_PROP_FRAME_WIDTH:
567 return frameWidth ? frameWidth : frameHeight*4 / 3;
568 case CV_CAP_PROP_FRAME_HEIGHT:
569 return frameHeight ? frameHeight : frameWidth*3 / 4;
570 case CV_CAP_PROP_FPS:
572 case CV_CAP_PROP_RECTIFICATION:
573 return rectify ? 1 : 0;
574 // case CV_CAP_PROP_BRIGHTNESS :
575 // case CV_CAP_PROP_CONTRAST :
576 // case CV_CAP_PROP_WHITE_BALANCE :
583 bool CvCaptureCAM_DC1394_v2_CPP::setProperty(int propId, double value)
587 case CV_CAP_PROP_FRAME_WIDTH:
590 frameWidth = cvRound(value);
593 case CV_CAP_PROP_FRAME_HEIGHT:
597 frameHeight = cvRound(value);
599 case CV_CAP_PROP_FPS:
604 case CV_CAP_PROP_RECTIFICATION:
605 if( cameraId != VIDERE )
607 rectify = fabs(value) > FLT_EPSILON;
616 bool CvCaptureCAM_DC1394_v2_CPP::getVidereCalibrationInfo( char* buf, int bufSize )
620 for( pos = 0; pos < bufSize - 4; pos += 4 )
622 uint32_t quad = getControlRegister(dcCam, 0xF0800 + pos);
623 if( quad == 0 || quad == 0xffffffff )
625 buf[pos] = (uchar)(quad >> 24);
626 buf[pos+1] = (uchar)(quad >> 16);
627 buf[pos+2] = (uchar)(quad >> 8);
628 buf[pos+3] = (uchar)(quad);
639 bool CvCaptureCAM_DC1394_v2_CPP::initVidereRectifyMaps( const char* info,
640 IplImage* ml[2], IplImage* mr[2] )
642 float identity_data[] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
643 CvMat l_rect = cvMat(3, 3, CV_32F, identity_data), r_rect = l_rect;
644 float l_intrinsic_data[] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
645 float r_intrinsic_data[] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
646 CvMat l_intrinsic = cvMat(3, 3, CV_32F, l_intrinsic_data);
647 CvMat r_intrinsic = cvMat(3, 3, CV_32F, r_intrinsic_data);
648 float l_distortion_data[] = {0,0,0,0,0}, r_distortion_data[] = {0,0,0,0,0};
649 CvMat l_distortion = cvMat(1, 5, CV_32F, l_distortion_data);
650 CvMat r_distortion = cvMat(1, 5, CV_32F, r_distortion_data);
651 IplImage* mx = cvCreateImage(cvGetSize(ml[0]), IPL_DEPTH_32F, 1);
652 IplImage* my = cvCreateImage(cvGetSize(ml[0]), IPL_DEPTH_32F, 1);
655 for( k = 0; k < 2; k++ )
657 const char* section_name = k == 0 ? "[left_camera]" : "[right_camera]";
658 static const char* param_names[] = { "f ", "fy", "Cx", "Cy" "kappa1", "kappa2", "tau1", "tau2", "kappa3", 0 };
659 const char* section_start = strstr( info, section_name );
660 CvMat* intrinsic = k == 0 ? &l_intrinsic : &r_intrinsic;
661 CvMat* distortion = k == 0 ? &l_distortion : &r_distortion;
662 CvMat* rectification = k == 0 ? &l_rect : &r_rect;
663 IplImage** dst = k == 0 ? ml : mr;
666 section_start += strlen(section_name);
667 for( j = 0; param_names[j] != 0; j++ )
669 const char* param_value_start = strstr(section_start, param_names[j]);
671 if(!param_value_start)
673 sscanf(param_value_start + strlen(param_names[j]), "%f", &val);
675 intrinsic->data.fl[j == 0 ? 0 : j == 1 ? 4 : j == 2 ? 2 : 5] = val;
677 distortion->data.fl[j - 4] = val;
679 if( param_names[j] != 0 )
682 // some sanity check for the principal point
683 if( fabs(mx->width*0.5 - intrinsic->data.fl[2]) > mx->width*0.1 ||
684 fabs(my->height*0.5 - intrinsic->data.fl[5]) > my->height*0.1 )
686 cvScale( &intrinsic, &intrinsic, 0.5 ); // try the corrected intrinsic matrix for 2x lower resolution
687 if( fabs(mx->width*0.5 - intrinsic->data.fl[2]) > mx->width*0.05 ||
688 fabs(my->height*0.5 - intrinsic->data.fl[5]) > my->height*0.05 )
689 cvScale( &intrinsic, &intrinsic, 2 ); // revert it back if the new variant is not much better
690 intrinsic->data.fl[8] = 1;
693 cvInitUndistortRectifyMap( intrinsic, distortion,
694 rectification, intrinsic, mx, my );
695 cvConvertMaps( mx, my, dst[0], dst[1] );
698 cvReleaseImage( &mx );
699 cvReleaseImage( &my );
704 CvCapture* cvCreateCameraCapture_DC1394_2(int index)
706 CvCaptureCAM_DC1394_v2_CPP* capture = new CvCaptureCAM_DC1394_v2_CPP;
708 if (capture->open(index))