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.
41 #include "precomp.hpp"
42 #include "opencv2/core.hpp"
43 #include "opencv2/imgproc.hpp"
47 #if defined TBB_INTERFACE_VERSION && TBB_INTERFACE_VERSION < 5000
66 #define CV_STREAM_TIMEOUT 2000
68 #define CV_DEPTH_STREAM 0
69 #define CV_COLOR_STREAM 1
71 #define CV_NUM_STREAMS 2
76 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
77 class CvCapture_OpenNI2 : public CvCapture
80 enum { DEVICE_DEFAULT=0, DEVICE_MS_KINECT=0, DEVICE_ASUS_XTION=1, DEVICE_MAX=1 };
82 static const int INVALID_PIXEL_VAL = 0;
83 static const int INVALID_COORDINATE_VAL = 0;
86 static const int DEFAULT_MAX_BUFFER_SIZE = 8;
88 static const int DEFAULT_MAX_BUFFER_SIZE = 2;
90 static const int DEFAULT_IS_CIRCLE_BUFFER = 0;
91 static const int DEFAULT_MAX_TIME_DURATION = 20;
93 CvCapture_OpenNI2(int index = 0);
94 CvCapture_OpenNI2(const char * filename);
95 virtual ~CvCapture_OpenNI2();
97 virtual double getProperty(int propIdx);
98 virtual bool setProperty(int probIdx, double propVal);
99 virtual bool grabFrame();
100 virtual IplImage* retrieveFrame(int outputType);
102 bool isOpened() const;
109 IplImage* getIplImagePtr();
114 static const int outputMapsTypesCount = 7;
116 static openni::VideoMode defaultColorOutputMode();
117 static openni::VideoMode defaultDepthOutputMode();
119 IplImage* retrieveDepthMap();
120 IplImage* retrievePointCloudMap();
121 IplImage* retrieveDisparityMap();
122 IplImage* retrieveDisparityMap_32F();
123 IplImage* retrieveValidDepthMask();
124 IplImage* retrieveBGRImage();
125 IplImage* retrieveGrayImage();
127 bool readCamerasParams();
129 double getDepthGeneratorProperty(int propIdx);
130 bool setDepthGeneratorProperty(int propIdx, double propVal);
131 double getImageGeneratorProperty(int propIdx);
132 bool setImageGeneratorProperty(int propIdx, double propVal);
133 double getCommonProperty(int propIdx);
134 bool setCommonProperty(int propIdx, double propVal);
137 openni::Device device;
138 bool isContextOpened;
139 openni::Recorder recorder;
141 // Data generators with its metadata
142 openni::VideoStream depth, color, **streams;
143 openni::VideoFrameRef depthFrame, colorFrame;
144 cv::Mat depthImage, colorImage;
146 int maxBufferSize, maxTimeDuration; // for approx sync
148 //cv::Ptr<ApproximateSyncGrabber> approxSyncGrabber;
151 // TODO find in OpenNI function to convert z->disparity and remove fields "baseline" and depthFocalLength_VGA
152 // Distance between IR projector and IR camera (in meters)
154 // Focal length for the IR camera in VGA resolution (in pixels)
155 int depthFocalLength_VGA;
157 // The value for shadow (occluded pixels)
159 // The value for pixels without a valid disparity measurement
164 std::vector<OutputMap> outputMaps;
167 IplImage* CvCapture_OpenNI2::OutputMap::getIplImagePtr()
172 iplHeader = IplImage(mat);
176 bool CvCapture_OpenNI2::isOpened() const
178 return isContextOpened;
181 openni::VideoMode CvCapture_OpenNI2::defaultColorOutputMode()
183 openni::VideoMode mode;
184 mode.setResolution(640, 480);
186 mode.setPixelFormat(openni::PIXEL_FORMAT_RGB888);
190 openni::VideoMode CvCapture_OpenNI2::defaultDepthOutputMode()
192 openni::VideoMode mode;
193 mode.setResolution(640, 480);
195 mode.setPixelFormat(openni::PIXEL_FORMAT_DEPTH_1_MM);
199 CvCapture_OpenNI2::CvCapture_OpenNI2( int index )
201 const char* deviceURI = openni::ANY_DEVICE;
202 openni::Status status;
203 int deviceType = DEVICE_DEFAULT;
205 noSampleValue = shadowValue = 0;
207 isContextOpened = false;
208 maxBufferSize = DEFAULT_MAX_BUFFER_SIZE;
209 isCircleBuffer = DEFAULT_IS_CIRCLE_BUFFER;
210 maxTimeDuration = DEFAULT_MAX_TIME_DURATION;
214 deviceType = index / 10;
218 if( deviceType > DEVICE_MAX )
221 // Initialize and configure the context.
222 status = openni::OpenNI::initialize();
224 if (status != openni::STATUS_OK)
226 CV_Error(CV_StsError, cv::format("Failed to initialize:", openni::OpenNI::getExtendedError()));
230 status = device.open(deviceURI);
231 if( status != openni::STATUS_OK )
233 CV_Error(CV_StsError, cv::format("OpenCVKinect: Device open failed see: %s\n", openni::OpenNI::getExtendedError()));
234 openni::OpenNI::shutdown();
238 //device.setDepthColorSyncEnabled(true);
241 status = depth.create(device, openni::SENSOR_DEPTH);
242 if (status == openni::STATUS_OK)
246 CV_DbgAssert(depth.setVideoMode(defaultDepthOutputMode()) == openni::STATUS_OK); // xn::DepthGenerator supports VGA only! (Jan 2011)
249 status = depth.start();
250 if (status != openni::STATUS_OK)
252 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::CvCapture_OpenNI2 : Couldn't start depth stream: %s\n", openni::OpenNI::getExtendedError()));
259 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::CvCapture_OpenNI2 : Couldn't find depth stream:: %s\n", openni::OpenNI::getExtendedError()));
262 // create a color object
263 status = color.create(device, openni::SENSOR_COLOR);
264 if (status == openni::STATUS_OK)
266 // Set map output mode.
269 CV_DbgAssert(color.setVideoMode(defaultColorOutputMode()) == openni::STATUS_OK);
271 status = color.start();
272 if (status != openni::STATUS_OK)
274 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::CvCapture_OpenNI2 : Couldn't start color stream: %s\n", openni::OpenNI::getExtendedError()));
281 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::CvCapture_OpenNI2 : Couldn't find color stream: %s\n", openni::OpenNI::getExtendedError()));
286 // if( deviceType == DEVICE_ASUS_XTION )
288 // //ps/asus specific
289 // imageGenerator.SetIntProperty("InputFormat", 1 /*XN_IO_IMAGE_FORMAT_YUV422*/);
290 // imageGenerator.SetPixelFormat(XN_PIXEL_FORMAT_RGB24);
291 // depthGenerator.SetIntProperty("RegistrationType", 1 /*XN_PROCESSING_HARDWARE*/);
294 if( !readCamerasParams() )
296 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::CvCapture_OpenNI2 : Could not read cameras parameters\n"));
299 streams = new openni::VideoStream*[CV_NUM_STREAMS];
300 streams[CV_DEPTH_STREAM] = &depth;
301 streams[CV_COLOR_STREAM] = &color;
303 outputMaps.resize( outputMapsTypesCount );
305 isContextOpened = true;
307 setProperty(CV_CAP_PROP_OPENNI_REGISTRATION, 1.0);
310 CvCapture_OpenNI2::CvCapture_OpenNI2(const char * filename)
312 openni::Status status;
314 isContextOpened = false;
315 maxBufferSize = DEFAULT_MAX_BUFFER_SIZE;
316 isCircleBuffer = DEFAULT_IS_CIRCLE_BUFFER;
317 maxTimeDuration = DEFAULT_MAX_TIME_DURATION;
319 // Initialize and configure the context.
320 status = openni::OpenNI::initialize();
322 if (status != openni::STATUS_OK)
324 CV_Error(CV_StsError, cv::format("Failed to initialize:", openni::OpenNI::getExtendedError()));
329 status = device.open(filename);
330 if( status != openni::STATUS_OK )
332 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::CvCapture_OpenNI2 : Failed to open input file (%s): %s\n", filename, openni::OpenNI::getExtendedError()));
336 if( !readCamerasParams() )
338 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::CvCapture_OpenNI2 : Could not read cameras parameters\n"));
342 outputMaps.resize( outputMapsTypesCount );
344 isContextOpened = true;
347 CvCapture_OpenNI2::~CvCapture_OpenNI2()
349 this->depthFrame.release();
350 this->colorFrame.release();
353 openni::OpenNI::shutdown();
356 bool CvCapture_OpenNI2::readCamerasParams()
358 double pixelSize = 0;
359 if (depth.getProperty<double>(XN_STREAM_PROPERTY_ZERO_PLANE_PIXEL_SIZE, &pixelSize) != openni::STATUS_OK)
361 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::readCamerasParams : Could not read pixel size!\n"));
365 // pixel size @ VGA = pixel size @ SXGA x 2
366 pixelSize *= 2.0; // in mm
368 // focal length of IR camera in pixels for VGA resolution
369 int zeroPlanDistance; // in mm
370 if (depth.getProperty(XN_STREAM_PROPERTY_ZERO_PLANE_DISTANCE, &zeroPlanDistance) != openni::STATUS_OK)
372 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::readCamerasParams : Could not read virtual plane distance!\n"));
376 if (depth.getProperty<double>(XN_STREAM_PROPERTY_EMITTER_DCMOS_DISTANCE, &baseline) != openni::STATUS_OK)
378 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::readCamerasParams : Could not read base line!\n"));
382 // baseline from cm -> mm
385 // focal length from mm -> pixels (valid for 640x480)
386 depthFocalLength_VGA = (int)((double)zeroPlanDistance / (double)pixelSize);
391 double CvCapture_OpenNI2::getProperty( int propIdx )
393 double propValue = 0;
397 int purePropIdx = propIdx & ~CV_CAP_OPENNI_GENERATORS_MASK;
399 if( (propIdx & CV_CAP_OPENNI_GENERATORS_MASK) == CV_CAP_OPENNI_IMAGE_GENERATOR )
401 propValue = getImageGeneratorProperty( purePropIdx );
403 else if( (propIdx & CV_CAP_OPENNI_GENERATORS_MASK) == CV_CAP_OPENNI_DEPTH_GENERATOR )
405 propValue = getDepthGeneratorProperty( purePropIdx );
409 propValue = getCommonProperty( purePropIdx );
416 bool CvCapture_OpenNI2::setProperty( int propIdx, double propValue )
421 int purePropIdx = propIdx & ~CV_CAP_OPENNI_GENERATORS_MASK;
423 if( (propIdx & CV_CAP_OPENNI_GENERATORS_MASK) == CV_CAP_OPENNI_IMAGE_GENERATOR )
425 isSet = setImageGeneratorProperty( purePropIdx, propValue );
427 else if( (propIdx & CV_CAP_OPENNI_GENERATORS_MASK) == CV_CAP_OPENNI_DEPTH_GENERATOR )
429 isSet = setDepthGeneratorProperty( purePropIdx, propValue );
433 isSet = setCommonProperty( purePropIdx, propValue );
440 double CvCapture_OpenNI2::getCommonProperty( int propIdx )
442 double propValue = 0;
446 // There is a set of properties that correspond to depth generator by default
447 // (is they are pass without particular generator flag). Two reasons of this:
448 // 1) We can assume that depth generator is the main one for depth sensor.
449 // 2) In the initial vertions of OpenNI integration to OpenCV the value of
450 // flag CV_CAP_OPENNI_DEPTH_GENERATOR was 0 (it isn't zero now).
451 case CV_CAP_PROP_OPENNI_GENERATOR_PRESENT :
452 case CV_CAP_PROP_FRAME_WIDTH :
453 case CV_CAP_PROP_FRAME_HEIGHT :
454 case CV_CAP_PROP_FPS :
455 case CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH :
456 case CV_CAP_PROP_OPENNI_BASELINE :
457 case CV_CAP_PROP_OPENNI_FOCAL_LENGTH :
458 case CV_CAP_PROP_OPENNI_REGISTRATION :
459 propValue = getDepthGeneratorProperty( propIdx );
461 case CV_CAP_PROP_OPENNI2_SYNC :
462 propValue = device.getDepthColorSyncEnabled();
463 case CV_CAP_PROP_OPENNI2_MIRROR:
465 bool isMirroring = color.getMirroringEnabled() && depth.getMirroringEnabled();
466 propValue = isMirroring ? 1.0 : 0.0;
470 CV_Error( CV_StsBadArg, cv::format("Such parameter (propIdx=%d) isn't supported for getting.\n", propIdx) );
476 bool CvCapture_OpenNI2::setCommonProperty( int propIdx, double propValue )
482 case CV_CAP_PROP_OPENNI2_MIRROR:
484 bool mirror = propValue > 0 ? true : false;
485 isSet = color.setMirroringEnabled(mirror) == openni::STATUS_OK;
486 isSet = depth.setMirroringEnabled(mirror) == openni::STATUS_OK;
489 // There is a set of properties that correspond to depth generator by default
490 // (is they are pass without particular generator flag).
491 case CV_CAP_PROP_OPENNI_REGISTRATION:
492 isSet = setDepthGeneratorProperty( propIdx, propValue );
494 case CV_CAP_PROP_OPENNI2_SYNC:
495 isSet = device.setDepthColorSyncEnabled(propValue) == openni::STATUS_OK;
498 CV_Error( CV_StsBadArg, cv::format("Such parameter (propIdx=%d) isn't supported for setting.\n", propIdx) );
504 double CvCapture_OpenNI2::getDepthGeneratorProperty( int propIdx )
506 double propValue = 0;
507 if( !depth.isValid() )
510 openni::VideoMode mode;
514 case CV_CAP_PROP_OPENNI_GENERATOR_PRESENT :
515 CV_DbgAssert(depth.isValid());
518 case CV_CAP_PROP_FRAME_WIDTH :
519 propValue = depth.getVideoMode().getResolutionX();
521 case CV_CAP_PROP_FRAME_HEIGHT :
522 propValue = depth.getVideoMode().getResolutionY();
524 case CV_CAP_PROP_FPS :
525 mode = depth.getVideoMode();
526 propValue = mode.getFps();
528 case CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH :
529 propValue = depth.getMaxPixelValue();
531 case CV_CAP_PROP_OPENNI_BASELINE :
532 propValue = baseline;
534 case CV_CAP_PROP_OPENNI_FOCAL_LENGTH :
535 propValue = (double)depthFocalLength_VGA;
537 case CV_CAP_PROP_OPENNI_REGISTRATION :
538 propValue = device.getImageRegistrationMode();
540 case CV_CAP_PROP_POS_MSEC :
541 propValue = (double)depthFrame.getTimestamp();
543 case CV_CAP_PROP_POS_FRAMES :
544 propValue = depthFrame.getFrameIndex();
547 CV_Error( CV_StsBadArg, cv::format("Depth generator does not support such parameter (propIdx=%d) for getting.\n", propIdx) );
553 bool CvCapture_OpenNI2::setDepthGeneratorProperty( int propIdx, double propValue )
557 CV_Assert( depth.isValid() );
561 case CV_CAP_PROP_OPENNI_REGISTRATION:
563 if( propValue < 1.0 ) // "on"
565 // if there isn't image generator (i.e. ASUS XtionPro doesn't have it)
566 // then the property isn't avaliable
567 if ( color.isValid() )
569 openni::ImageRegistrationMode mode = propValue < 1.0 ? openni::IMAGE_REGISTRATION_OFF : openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR;
570 if( !device.getImageRegistrationMode() == mode )
572 if (device.isImageRegistrationModeSupported(mode))
574 openni::Status status = device.setImageRegistrationMode(mode);
575 if( status != openni::STATUS_OK )
576 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::setDepthGeneratorProperty : %s\n", openni::OpenNI::getExtendedError()));
581 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::setDepthGeneratorProperty : Unsupported viewpoint.\n"));
589 openni::Status status = device.setImageRegistrationMode(openni::IMAGE_REGISTRATION_OFF);
590 if( status != openni::STATUS_OK )
591 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::setDepthGeneratorProperty : %s\n", openni::OpenNI::getExtendedError()));
598 CV_Error( CV_StsBadArg, cv::format("Depth generator does not support such parameter (propIdx=%d) for setting.\n", propIdx) );
604 double CvCapture_OpenNI2::getImageGeneratorProperty( int propIdx )
606 double propValue = 0.;
607 if( !color.isValid() )
610 openni::VideoMode mode;
613 case CV_CAP_PROP_OPENNI_GENERATOR_PRESENT :
614 CV_DbgAssert( color.isValid() );
617 case CV_CAP_PROP_FRAME_WIDTH :
618 propValue = color.getVideoMode().getResolutionX();
620 case CV_CAP_PROP_FRAME_HEIGHT :
621 propValue = color.getVideoMode().getResolutionY();
623 case CV_CAP_PROP_FPS :
624 propValue = color.getVideoMode().getFps();
626 case CV_CAP_PROP_POS_MSEC :
627 propValue = (double)colorFrame.getTimestamp();
629 case CV_CAP_PROP_POS_FRAMES :
630 propValue = (double)colorFrame.getFrameIndex();
633 CV_Error( CV_StsBadArg, cv::format("Image generator does not support such parameter (propIdx=%d) for getting.\n", propIdx) );
639 bool CvCapture_OpenNI2::setImageGeneratorProperty(int propIdx, double propValue)
642 if( !color.isValid() )
647 case CV_CAP_PROP_OPENNI_OUTPUT_MODE :
649 openni::VideoMode mode;
651 switch( cvRound(propValue) )
653 case CV_CAP_OPENNI_VGA_30HZ :
654 mode.setResolution(640,480);
657 case CV_CAP_OPENNI_SXGA_15HZ :
658 mode.setResolution(1280, 960);
661 case CV_CAP_OPENNI_SXGA_30HZ :
662 mode.setResolution(1280, 960);
665 case CV_CAP_OPENNI_QVGA_30HZ :
666 mode.setResolution(320, 240);
669 case CV_CAP_OPENNI_QVGA_60HZ :
670 mode.setResolution(320, 240);
674 CV_Error( CV_StsBadArg, "Unsupported image generator output mode.\n");
677 openni::Status status = color.setVideoMode( mode );
678 if( status != openni::STATUS_OK )
679 CV_Error(CV_StsError, cv::format("CvCapture_OpenNI2::setImageGeneratorProperty : %s\n", openni::OpenNI::getExtendedError()));
685 CV_Error( CV_StsBadArg, cv::format("Image generator does not support such parameter (propIdx=%d) for setting.\n", propIdx) );
691 bool CvCapture_OpenNI2::grabFrame()
696 bool isGrabbed = false;
698 openni::Status status = openni::OpenNI::waitForAnyStream(streams, CV_NUM_STREAMS, ¤tStream, CV_STREAM_TIMEOUT);
699 if( status != openni::STATUS_OK )
702 if( depth.isValid() )
703 depth.readFrame(&depthFrame);
705 color.readFrame(&colorFrame);
711 inline void getDepthMapFromMetaData(const openni::VideoFrameRef& depthMetaData, cv::Mat& depthMap, int noSampleValue, int shadowValue)
713 depthMap.create(depthMetaData.getHeight(), depthMetaData.getWidth(), CV_16UC1);
714 depthMap.data = (uchar*)depthMetaData.getData();
716 cv::Mat badMask = (depthMap == (double)noSampleValue) | (depthMap == (double)shadowValue) | (depthMap == 0);
718 // mask the pixels with invalid depth
719 depthMap.setTo( cv::Scalar::all( CvCapture_OpenNI2::INVALID_PIXEL_VAL ), badMask );
722 IplImage* CvCapture_OpenNI2::retrieveDepthMap()
724 if( !depth.isValid() )
727 getDepthMapFromMetaData( depthFrame, outputMaps[CV_CAP_OPENNI_DEPTH_MAP].mat, noSampleValue, shadowValue );
729 return outputMaps[CV_CAP_OPENNI_DEPTH_MAP].getIplImagePtr();
732 IplImage* CvCapture_OpenNI2::retrievePointCloudMap()
734 if( !depthFrame.isValid() )
738 getDepthMapFromMetaData(depthFrame, depthImg, noSampleValue, shadowValue);
740 const int badPoint = INVALID_PIXEL_VAL;
741 const float badCoord = INVALID_COORDINATE_VAL;
742 int cols = depthFrame.getWidth(), rows = depthFrame.getHeight();
743 cv::Mat pointCloud_XYZ( rows, cols, CV_32FC3, cv::Scalar::all(badPoint) );
745 float worldX, worldY, worldZ;
746 for( int y = 0; y < rows; y++ )
748 for (int x = 0; x < cols; x++)
750 openni::CoordinateConverter::convertDepthToWorld(depth, x, y, depthImg.at<unsigned short>(y, x), &worldX, &worldY, &worldZ);
752 if (depthImg.at<unsigned short>(y, x) == badPoint) // not valid
753 pointCloud_XYZ.at<cv::Point3f>(y, x) = cv::Point3f(badCoord, badCoord, badCoord);
756 pointCloud_XYZ.at<cv::Point3f>(y, x) = cv::Point3f(worldX*0.001f, worldY*0.001f, worldZ*0.001f); // from mm to meters
761 outputMaps[CV_CAP_OPENNI_POINT_CLOUD_MAP].mat = pointCloud_XYZ;
763 return outputMaps[CV_CAP_OPENNI_POINT_CLOUD_MAP].getIplImagePtr();
766 static void computeDisparity_32F( const openni::VideoFrameRef& depthMetaData, cv::Mat& disp, double baseline, int F, int noSampleValue, int shadowValue)
769 getDepthMapFromMetaData( depthMetaData, depth, noSampleValue, shadowValue );
770 CV_Assert( depth.type() == CV_16UC1 );
772 // disparity = baseline * F / z;
774 float mult = (float)(baseline /*mm*/ * F /*pixels*/);
776 disp.create( depth.size(), CV_32FC1);
777 disp = cv::Scalar::all( CvCapture_OpenNI2::INVALID_PIXEL_VAL );
778 for( int y = 0; y < disp.rows; y++ )
780 for( int x = 0; x < disp.cols; x++ )
782 unsigned short curDepth = depth.at<unsigned short>(y,x);
783 if( curDepth != CvCapture_OpenNI2::INVALID_PIXEL_VAL )
784 disp.at<float>(y,x) = mult / curDepth;
789 IplImage* CvCapture_OpenNI2::retrieveDisparityMap()
791 if (!depthFrame.isValid())
795 computeDisparity_32F(depthFrame, disp32, baseline, depthFocalLength_VGA, noSampleValue, shadowValue);
797 disp32.convertTo( outputMaps[CV_CAP_OPENNI_DISPARITY_MAP].mat, CV_8UC1 );
799 return outputMaps[CV_CAP_OPENNI_DISPARITY_MAP].getIplImagePtr();
802 IplImage* CvCapture_OpenNI2::retrieveDisparityMap_32F()
804 if (!depthFrame.isValid())
807 computeDisparity_32F(depthFrame, outputMaps[CV_CAP_OPENNI_DISPARITY_MAP_32F].mat, baseline, depthFocalLength_VGA, noSampleValue, shadowValue);
809 return outputMaps[CV_CAP_OPENNI_DISPARITY_MAP_32F].getIplImagePtr();
812 IplImage* CvCapture_OpenNI2::retrieveValidDepthMask()
814 if (!depthFrame.isValid())
818 getDepthMapFromMetaData(depthFrame, depth, noSampleValue, shadowValue);
820 outputMaps[CV_CAP_OPENNI_VALID_DEPTH_MASK].mat = depth != CvCapture_OpenNI2::INVALID_PIXEL_VAL;
822 return outputMaps[CV_CAP_OPENNI_VALID_DEPTH_MASK].getIplImagePtr();
825 inline void getBGRImageFromMetaData( const openni::VideoFrameRef& imageMetaData, cv::Mat& bgrImage )
828 if( imageMetaData.getVideoMode().getPixelFormat() != openni::PIXEL_FORMAT_RGB888 )
829 CV_Error( CV_StsUnsupportedFormat, "Unsupported format of grabbed image\n" );
831 bgrImage.create(imageMetaData.getHeight(), imageMetaData.getWidth(), CV_8UC3);
832 bufferImage.create(imageMetaData.getHeight(), imageMetaData.getWidth(), CV_8UC3);
833 bufferImage.data = (uchar*)imageMetaData.getData();
835 cv::cvtColor(bufferImage, bgrImage, cv::COLOR_RGB2BGR);
838 IplImage* CvCapture_OpenNI2::retrieveBGRImage()
840 if( !color.isValid() )
843 getBGRImageFromMetaData( colorFrame, outputMaps[CV_CAP_OPENNI_BGR_IMAGE].mat );
845 return outputMaps[CV_CAP_OPENNI_BGR_IMAGE].getIplImagePtr();
848 IplImage* CvCapture_OpenNI2::retrieveGrayImage()
850 if (!colorFrame.isValid())
853 CV_Assert(colorFrame.getVideoMode().getPixelFormat() == openni::PIXEL_FORMAT_RGB888); // RGB
856 getBGRImageFromMetaData(colorFrame, rgbImage);
857 cv::cvtColor( rgbImage, outputMaps[CV_CAP_OPENNI_GRAY_IMAGE].mat, CV_BGR2GRAY );
859 return outputMaps[CV_CAP_OPENNI_GRAY_IMAGE].getIplImagePtr();
862 IplImage* CvCapture_OpenNI2::retrieveFrame( int outputType )
865 CV_Assert( outputType < outputMapsTypesCount && outputType >= 0);
867 if( outputType == CV_CAP_OPENNI_DEPTH_MAP )
869 image = retrieveDepthMap();
871 else if( outputType == CV_CAP_OPENNI_POINT_CLOUD_MAP )
873 image = retrievePointCloudMap();
875 else if( outputType == CV_CAP_OPENNI_DISPARITY_MAP )
877 image = retrieveDisparityMap();
879 else if( outputType == CV_CAP_OPENNI_DISPARITY_MAP_32F )
881 image = retrieveDisparityMap_32F();
883 else if( outputType == CV_CAP_OPENNI_VALID_DEPTH_MASK )
885 image = retrieveValidDepthMask();
887 else if( outputType == CV_CAP_OPENNI_BGR_IMAGE )
889 image = retrieveBGRImage();
891 else if( outputType == CV_CAP_OPENNI_GRAY_IMAGE )
893 image = retrieveGrayImage();
899 CvCapture* cvCreateCameraCapture_OpenNI( int index )
901 CvCapture_OpenNI2* capture = new CvCapture_OpenNI2( index );
903 if( capture->isOpened() )
910 CvCapture* cvCreateFileCapture_OpenNI( const char* filename )
912 CvCapture_OpenNI2* capture = new CvCapture_OpenNI2( filename );
914 if( capture->isOpened() )