diff --git a/doc/user_guide/ug_intelperc.rst b/doc/user_guide/ug_intelperc.rst new file mode 100644 index 0000000000..d00a2f9009 --- /dev/null +++ b/doc/user_guide/ug_intelperc.rst @@ -0,0 +1,80 @@ +******* +HighGUI +******* + +.. highlight:: cpp + +Using Creative Senz3D and other Intel Perceptual Computing SDK compatible depth sensors +====================================================== + +Depth sensors compatible with Intel Perceptual Computing SDK are supported through ``VideoCapture`` class. Depth map, RGB image and some other formats of output can be retrieved by using familiar interface of ``VideoCapture``. + +In order to use depth sensor with OpenCV you should do the following preliminary steps: + +#. + Install Intel Perceptual Computing SDK (from here http://www.intel.com/software/perceptual). + +#. + Configure OpenCV with Intel Perceptual Computing SDK support by setting ``WITH_INTELPERC`` flag in CMake. If Intel Perceptual Computing SDK is found in install folders OpenCV will be built with Intel Perceptual Computing SDK library (see a status ``INTELPERC`` in CMake log). If CMake process doesn't find Intel Perceptual Computing SDK installation folder automatically, the user should change corresponding CMake variables ``INTELPERC_LIB_DIR`` and ``INTELPERC_INCLUDE_DIR`` to the proper value. + +#. + Build OpenCV. + +VideoCapture can retrieve the following data: + +#. + data given from depth generator: + * ``CV_CAP_INTELPERC_DEPTH_MAP`` - each pixel is a 16-bit integer. The value indicates the distance from an object to the camera's XY plane or the Cartesian depth. (CV_16UC1) + * ``CV_CAP_INTELPERC_UVDEPTH_MAP`` - each pixel contains two 32-bit floating point values in the range of 0-1, representing the mapping of depth coordinates to the color coordinates. (CV_32FC2) + * ``CV_CAP_INTELPERC_IR_MAP`` - each pixel is a 16-bit integer. The value indicates the intensity of the reflected laser beam. (CV_16UC1) +#. + data given from RGB image generator: + * ``CV_CAP_INTELPERC_IMAGE`` - color image. (CV_8UC3) + +In order to get depth map from depth sensor use ``VideoCapture::operator >>``, e. g. :: + + VideoCapture capture( CV_CAP_INTELPERC ); + for(;;) + { + Mat depthMap; + capture >> depthMap; + + if( waitKey( 30 ) >= 0 ) + break; + } + +For getting several data maps use ``VideoCapture::grab`` and ``VideoCapture::retrieve``, e.g. :: + + VideoCapture capture(CV_CAP_INTELPERC); + for(;;) + { + Mat depthMap; + Mat image; + Mat irImage; + + capture.grab(); + + capture.retrieve( depthMap, CV_CAP_INTELPERC_DEPTH_MAP ); + capture.retrieve( image, CV_CAP_INTELPERC_IMAGE ); + capture.retrieve( irImage, CV_CAP_INTELPERC_IR_MAP); + + if( waitKey( 30 ) >= 0 ) + break; + } + +For setting and getting some property of sensor` data generators use ``VideoCapture::set`` and ``VideoCapture::get`` methods respectively, e.g. :: + + VideoCapture capture( CV_CAP_INTELPERC ); + capture.set( CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_PROFILE_IDX, 0 ); + cout << "FPS " << capture.get( CV_CAP_INTELPERC_DEPTH_GENERATOR+CV_CAP_PROP_FPS ) << endl; + +Since two types of sensor's data generators are supported (image generator and depth generator), there are two flags that should be used to set/get property of the needed generator: + +* CV_CAP_INTELPERC_IMAGE_GENERATOR -- a flag for access to the image generator properties. + +* CV_CAP_INTELPERC_DEPTH_GENERATOR -- a flag for access to the depth generator properties. This flag value is assumed by default if neither of the two possible values of the property is set. + +For more information please refer to the example of usage intelperc_capture.cpp_ in ``opencv/samples/cpp`` folder. + +.. _intelperc_capture.cpp: https://github.com/Itseez/opencv/tree/master/samples/cpp/intelperc_capture.cpp + diff --git a/doc/user_guide/user_guide.rst b/doc/user_guide/user_guide.rst index de9edcb683..76cf756f85 100644 --- a/doc/user_guide/user_guide.rst +++ b/doc/user_guide/user_guide.rst @@ -9,3 +9,4 @@ OpenCV User Guide ug_features2d.rst ug_highgui.rst ug_traincascade.rst + ug_intelperc.rst diff --git a/modules/highgui/include/opencv2/highgui/highgui_c.h b/modules/highgui/include/opencv2/highgui/highgui_c.h index 99f453385d..862fa053a6 100644 --- a/modules/highgui/include/opencv2/highgui/highgui_c.h +++ b/modules/highgui/include/opencv2/highgui/highgui_c.h @@ -480,9 +480,9 @@ enum CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_VERT = 11007, // Intel PerC streams - CV_CAP_INTELPERC_DEPTH_STREAM = 1 << 31, - CV_CAP_INTELPERC_IMAGE_STREAM = 1 << 30, - CV_CAP_INTELPERC_STREAMS_MASK = CV_CAP_INTELPERC_DEPTH_STREAM + CV_CAP_INTELPERC_IMAGE_STREAM, + CV_CAP_INTELPERC_DEPTH_GENERATOR = 1 << 31, + CV_CAP_INTELPERC_IMAGE_GENERATOR = 1 << 30, + CV_CAP_INTELPERC_GENERATORS_MASK = CV_CAP_INTELPERC_DEPTH_GENERATOR + CV_CAP_INTELPERC_IMAGE_GENERATOR, }; enum diff --git a/modules/highgui/src/cap_intelperc.cpp b/modules/highgui/src/cap_intelperc.cpp index d562dc0c8e..910a6f748a 100644 --- a/modules/highgui/src/cap_intelperc.cpp +++ b/modules/highgui/src/cap_intelperc.cpp @@ -195,6 +195,11 @@ protected: int m_frameIdx; pxcU64 m_timeStampStartNS; double m_timeStamp; + + virtual bool validProfile(const PXCCapture::VideoStream::ProfileInfo& /*pinfo*/) + { + return true; + } void enumProfiles() { m_profiles.clear(); @@ -207,7 +212,8 @@ protected: sts = m_stream->QueryProfile(profidx, &pinfo); if (PXC_STATUS_NO_ERROR > sts) break; - m_profiles.push_back(pinfo); + if (validProfile(pinfo)) + m_profiles.push_back(pinfo); } } virtual bool prepareIplImage(PXCImage *pxcImage) = 0; @@ -552,6 +558,11 @@ public: { return m_frameUV.retrieveFrame(); } +protected: + virtual bool validProfile(const PXCCapture::VideoStream::ProfileInfo& pinfo) + { + return (PXCImage::COLOR_FORMAT_DEPTH == pinfo.imageInfo.format); + } protected: FrameInternal m_frameDepth; FrameInternal m_frameIR; @@ -609,12 +620,16 @@ public: virtual double getProperty(int propIdx) { double propValue = 0; - int purePropIdx = propIdx & ~CV_CAP_INTELPERC_STREAMS_MASK; - if (CV_CAP_INTELPERC_IMAGE_STREAM == (propIdx & CV_CAP_INTELPERC_STREAMS_MASK)) + int purePropIdx = propIdx & ~CV_CAP_INTELPERC_GENERATORS_MASK; + if (CV_CAP_INTELPERC_IMAGE_GENERATOR == (propIdx & CV_CAP_INTELPERC_GENERATORS_MASK)) { propValue = m_imageStream.getProperty(purePropIdx); } - else if (CV_CAP_INTELPERC_DEPTH_STREAM == (propIdx & CV_CAP_INTELPERC_STREAMS_MASK)) + else if (CV_CAP_INTELPERC_DEPTH_GENERATOR == (propIdx & CV_CAP_INTELPERC_GENERATORS_MASK)) + { + propValue = m_depthStream.getProperty(purePropIdx); + } + else { propValue = m_depthStream.getProperty(purePropIdx); } @@ -623,12 +638,16 @@ public: virtual bool setProperty(int propIdx, double propVal) { bool isSet = false; - int purePropIdx = propIdx & ~CV_CAP_INTELPERC_STREAMS_MASK; - if (CV_CAP_INTELPERC_IMAGE_STREAM == (propIdx & CV_CAP_INTELPERC_STREAMS_MASK)) + int purePropIdx = propIdx & ~CV_CAP_INTELPERC_GENERATORS_MASK; + if (CV_CAP_INTELPERC_IMAGE_GENERATOR == (propIdx & CV_CAP_INTELPERC_GENERATORS_MASK)) { isSet = m_imageStream.setProperty(purePropIdx, propVal); } - else if (CV_CAP_INTELPERC_DEPTH_STREAM == (propIdx & CV_CAP_INTELPERC_STREAMS_MASK)) + else if (CV_CAP_INTELPERC_DEPTH_GENERATOR == (propIdx & CV_CAP_INTELPERC_GENERATORS_MASK)) + { + isSet = m_depthStream.setProperty(purePropIdx, propVal); + } + else { isSet = m_depthStream.setProperty(purePropIdx, propVal); } diff --git a/samples/cpp/intelperc_capture.cpp b/samples/cpp/intelperc_capture.cpp index 7744377c5a..30471c3471 100644 --- a/samples/cpp/intelperc_capture.cpp +++ b/samples/cpp/intelperc_capture.cpp @@ -107,48 +107,48 @@ static void parseCMDLine(int argc, char* argv[]) static void printStreamProperties(VideoCapture &capture) { - size_t profilesCount = (size_t)capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_INTELPERC_PROFILE_COUNT); + size_t profilesCount = (size_t)capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_INTELPERC_PROFILE_COUNT); cout << "Image stream." << endl; - cout << " Brightness = " << capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_BRIGHTNESS) << endl; - cout << " Contrast = " << capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_CONTRAST) << endl; - cout << " Saturation = " << capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_SATURATION) << endl; - cout << " Hue = " << capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_HUE) << endl; - cout << " Gamma = " << capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_GAMMA) << endl; - cout << " Sharpness = " << capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_SHARPNESS) << endl; - cout << " Gain = " << capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_GAIN) << endl; - cout << " Backligh = " << capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_BACKLIGHT) << endl; + cout << " Brightness = " << capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_BRIGHTNESS) << endl; + cout << " Contrast = " << capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_CONTRAST) << endl; + cout << " Saturation = " << capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_SATURATION) << endl; + cout << " Hue = " << capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_HUE) << endl; + cout << " Gamma = " << capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_GAMMA) << endl; + cout << " Sharpness = " << capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_SHARPNESS) << endl; + cout << " Gain = " << capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_GAIN) << endl; + cout << " Backligh = " << capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_BACKLIGHT) << endl; cout << "Image streams profiles:" << endl; for (size_t i = 0; i < profilesCount; i++) { - capture.set(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_INTELPERC_PROFILE_IDX, (double)i); + capture.set(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_INTELPERC_PROFILE_IDX, (double)i); cout << " Profile[" << i << "]: "; cout << "width = " << - (int)capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_FRAME_WIDTH); + (int)capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_FRAME_WIDTH); cout << ", height = " << - (int)capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_FRAME_HEIGHT); + (int)capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_FRAME_HEIGHT); cout << ", fps = " << - capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_FPS); + capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_FPS); cout << endl; } - profilesCount = (size_t)capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_INTELPERC_PROFILE_COUNT); + profilesCount = (size_t)capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_PROFILE_COUNT); cout << "Depth stream." << endl; - cout << " Low confidence value = " << capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE) << endl; - cout << " Saturation value = " << capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE) << endl; - cout << " Confidence threshold = " << capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_INTELPERC_DEPTH_CONFIDENCE_THRESHOLD) << endl; - cout << " Focal length = (" << capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_HORZ) << ", " - << capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_VERT) << ")" << endl; + cout << " Low confidence value = " << capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE) << endl; + cout << " Saturation value = " << capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE) << endl; + cout << " Confidence threshold = " << capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_DEPTH_CONFIDENCE_THRESHOLD) << endl; + cout << " Focal length = (" << capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_HORZ) << ", " + << capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_VERT) << ")" << endl; cout << "Depth streams profiles:" << endl; for (size_t i = 0; i < profilesCount; i++) { - capture.set(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_INTELPERC_PROFILE_IDX, (double)i); + capture.set(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_PROFILE_IDX, (double)i); cout << " Profile[" << i << "]: "; cout << "width = " << - (int)capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_FRAME_WIDTH); + (int)capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_FRAME_WIDTH); cout << ", height = " << - (int)capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_FRAME_HEIGHT); + (int)capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_FRAME_HEIGHT); cout << ", fps = " << - capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_FPS); + capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_FPS); cout << endl; } } @@ -227,8 +227,8 @@ static void imshowIR(const char *winname, Mat &ir) } static void imshowDepth(const char *winname, Mat &depth, VideoCapture &capture) { - short lowValue = (short)capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE); - short saturationValue = (short)capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE); + short lowValue = (short)capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE); + short saturationValue = (short)capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE); Mat image; if (g_showClosedPoint) @@ -302,7 +302,7 @@ int _tmain(int argc, char* argv[]) if (-1 != g_imageStreamProfileIdx) { - if (!capture.set(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_INTELPERC_PROFILE_IDX, (double)g_imageStreamProfileIdx)) + if (!capture.set(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_INTELPERC_PROFILE_IDX, (double)g_imageStreamProfileIdx)) { cerr << "Can not setup a image stream." << endl; return -1; @@ -310,7 +310,7 @@ int _tmain(int argc, char* argv[]) } if (-1 != g_depthStreamProfileIdx) { - if (!capture.set(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_INTELPERC_PROFILE_IDX, (double)g_depthStreamProfileIdx)) + if (!capture.set(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_PROFILE_IDX, (double)g_depthStreamProfileIdx)) { cerr << "Can not setup a depth stream." << endl; return -1; @@ -318,7 +318,7 @@ int _tmain(int argc, char* argv[]) } else if (g_irStreamShow) { - if (!capture.set(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_INTELPERC_PROFILE_IDX, 0.0)) + if (!capture.set(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_PROFILE_IDX, 0.0)) { cerr << "Can not setup a IR stream." << endl; return -1; @@ -332,9 +332,9 @@ int _tmain(int argc, char* argv[]) //Setup additional properies only after set profile of the stream if ( (-10000.0 < g_imageBrightness) && (g_imageBrightness < 10000.0)) - capture.set(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_BRIGHTNESS, g_imageBrightness); + capture.set(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_BRIGHTNESS, g_imageBrightness); if ( (0 < g_imageContrast) && (g_imageContrast < 10000.0)) - capture.set(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_BRIGHTNESS, g_imageContrast); + capture.set(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_BRIGHTNESS, g_imageContrast); int frame = 0; for(;;frame++) @@ -365,10 +365,10 @@ int _tmain(int argc, char* argv[]) if (g_printTiming) { - cout << "Image frame: " << capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_POS_FRAMES) - << ", Depth(IR) frame: " << capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_POS_FRAMES) << endl; - cout << "Image frame: " << capture.get(CV_CAP_INTELPERC_IMAGE_STREAM | CV_CAP_PROP_POS_MSEC) - << ", Depth(IR) frame: " << capture.get(CV_CAP_INTELPERC_DEPTH_STREAM | CV_CAP_PROP_POS_MSEC) << endl; + cout << "Image frame: " << capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_POS_FRAMES) + << ", Depth(IR) frame: " << capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_POS_FRAMES) << endl; + cout << "Image frame: " << capture.get(CV_CAP_INTELPERC_IMAGE_GENERATOR | CV_CAP_PROP_POS_MSEC) + << ", Depth(IR) frame: " << capture.get(CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_POS_MSEC) << endl; } if( waitKey(30) >= 0 ) break;