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
adaptBufferStereoLocal(dc1394video_frame_t * in,dc1394video_frame_t * out)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
dc1394_deinterlace_stereo_frames_fixed(dc1394video_frame_t * in,dc1394video_frame_t * out,dc1394stereo_method_t method)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
getControlRegister(dc1394camera_t * camera,uint64_t offset)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
CvDC1394()182 CvDC1394::CvDC1394()
183 {
184 dc = dc1394_new();
185 FD_ZERO(&camFds);
186 }
187
~CvDC1394()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();
~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);
getCaptureDomain()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 };
CvCaptureCAM_DC1394_v2_CPP()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
startCapture()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
open(int index)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
close()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
grabFrame()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
retrieveFrame(int idx)651 IplImage* CvCaptureCAM_DC1394_v2_CPP::retrieveFrame(int idx)
652 {
653 return 0 <= idx && idx < nimages ? img[idx] : 0;
654 }
655
getProperty(int propId) const656 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
setProperty(int propId,double value)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
getVidereCalibrationInfo(char * buf,int bufSize)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
initVidereRectifyMaps(const char * info,IplImage * ml[2],IplImage * mr[2])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
cvCreateCameraCapture_DC1394_2(int index)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