From 6051e27a09ee3d2092475a138a415aff86fee0e0 Mon Sep 17 00:00:00 2001 From: Alexander Shishkov Date: Mon, 12 Mar 2012 16:07:42 +0000 Subject: [PATCH] added support of Asus XtionPRO (thanks to Gustav Karlsson for his patches) #1657 --- .../highgui/include/opencv2/highgui/highgui_c.h | 5 +- modules/highgui/src/cap_openni.cpp | 101 ++++++++++++++------- .../cpp/{kinect_maps.cpp => openni_capture.cpp} | 55 +++++++---- 3 files changed, 112 insertions(+), 49 deletions(-) rename samples/cpp/{kinect_maps.cpp => openni_capture.cpp} (81%) diff --git a/modules/highgui/include/opencv2/highgui/highgui_c.h b/modules/highgui/include/opencv2/highgui/highgui_c.h index c2adf70..d23b0b2 100644 --- a/modules/highgui/include/opencv2/highgui/highgui_c.h +++ b/modules/highgui/include/opencv2/highgui/highgui_c.h @@ -370,6 +370,7 @@ enum CV_CAP_PROP_GUID =29, CV_CAP_PROP_ISO_SPEED =30, CV_CAP_PROP_MAX_DC1394 =31, + CV_CAP_PROP_IMAGE_GENERATOR_PRESENT = 32, CV_CAP_PROP_AUTOGRAB =1024, // property for highgui class CvCapture_Android only CV_CAP_PROP_SUPPORTED_PREVIEW_SIZES_STRING=1025, // readonly, tricky property, returns cpnst char* indeed CV_CAP_PROP_PREVIEW_FORMAT=1026, // readonly, tricky property, returns cpnst char* indeed @@ -377,6 +378,7 @@ enum CV_CAP_OPENNI_DEPTH_GENERATOR = 0, CV_CAP_OPENNI_IMAGE_GENERATOR = 1 << 31, CV_CAP_OPENNI_GENERATORS_MASK = 1 << 31, + CV_CAP_OPENNI_PROP_IMAGE_GENERATOR_PRESENT = CV_CAP_OPENNI_IMAGE_GENERATOR + CV_CAP_PROP_IMAGE_GENERATOR_PRESENT, // Properties of cameras available through OpenNI interfaces CV_CAP_PROP_OPENNI_OUTPUT_MODE = 100, @@ -445,7 +447,8 @@ enum enum { CV_CAP_OPENNI_VGA_30HZ = 0, - CV_CAP_OPENNI_SXGA_15HZ = 1 + CV_CAP_OPENNI_SXGA_15HZ = 1, + CV_CAP_OPENNI_SXGA_30HZ = 2 }; //supported by Android camera output formats diff --git a/modules/highgui/src/cap_openni.cpp b/modules/highgui/src/cap_openni.cpp index c470be7..2a16a1c 100644 --- a/modules/highgui/src/cap_openni.cpp +++ b/modules/highgui/src/cap_openni.cpp @@ -38,7 +38,6 @@ // the use of this software, even if advised of the possibility of such damage. // //M*/ - #include "precomp.hpp" #include "opencv2/core/core.hpp" #include "opencv2/imgproc/imgproc.hpp" @@ -67,7 +66,7 @@ const std::string XMLConfig = "" "" "" - "" + "" "" "" "" @@ -134,6 +133,7 @@ protected: xn::DepthMetaData depthMetaData; XnMapOutputMode depthOutputMode; + bool m_isImageGeneratorPresent; xn::ImageGenerator imageGenerator; xn::ImageMetaData imageMetaData; XnMapOutputMode imageOutputMode; @@ -241,17 +241,34 @@ CvCapture_OpenNI::CvCapture_OpenNI( int index ) return; } - imageGenerator.Create( context ); + // enumerate the nodes to find if image generator is present + xn::NodeInfoList Imagelist; + status = context.EnumerateExistingNodes( Imagelist, XN_NODE_TYPE_IMAGE ); if( status != XN_STATUS_OK ) { - std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to create image generator: " - << std::string(xnGetStatusString(status)) << std::endl; + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to enumerate Image Generators: " + << std::string(xnGetStatusString(status)) << std::endl; return; } + if(Imagelist.IsEmpty()) + { + m_isImageGeneratorPresent = FALSE; + } + else + { + m_isImageGeneratorPresent = TRUE; + imageGenerator.Create( context); + if( status != XN_STATUS_OK ) + { + std::cerr << "CvCapture_OpenNI::CvCapture_OpenNI : Failed to create image generator: " + << std::string(xnGetStatusString(status)) << std::endl; + return; + } + } // Set map output mode. CV_Assert( depthGenerator.SetMapOutputMode( depthOutputMode ) == XN_STATUS_OK ); // xn::DepthGenerator supports VGA only! (Jan 2011) - CV_Assert( imageGenerator.SetMapOutputMode( imageOutputMode ) == XN_STATUS_OK ); + CV_Assert( m_isImageGeneratorPresent ? ( imageGenerator.SetMapOutputMode( imageOutputMode ) == XN_STATUS_OK ) : TRUE); // Start generating data. status = context.StartGeneratingAll(); @@ -424,22 +441,28 @@ bool CvCapture_OpenNI::setDepthGeneratorProperty( int propIdx, double propValue { if( propValue != 0.0 ) // "on" { - CV_Assert( imageGenerator.IsValid() ); - if( !depthGenerator.GetAlternativeViewPointCap().IsViewPointAs(imageGenerator) ) + // if no Image Generator is present i.e. ASUS XtionPro the imageGenerator cannot be used + if( m_isImageGeneratorPresent ) { - if( depthGenerator.GetAlternativeViewPointCap().IsViewPointSupported(imageGenerator) ) + CV_Assert( imageGenerator.IsValid() ); + if( !depthGenerator.GetAlternativeViewPointCap().IsViewPointAs(imageGenerator) ) { - XnStatus status = depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator); - if( status != XN_STATUS_OK ) - std::cerr << "CvCapture_OpenNI::setDepthGeneratorProperty : " << xnGetStatusString(status) << std::endl; + if( depthGenerator.GetAlternativeViewPointCap().IsViewPointSupported(imageGenerator) ) + { + XnStatus status = depthGenerator.GetAlternativeViewPointCap().SetViewPoint(imageGenerator); + if( status != XN_STATUS_OK ) + std::cerr << "CvCapture_OpenNI::setDepthGeneratorProperty : " << xnGetStatusString(status) << std::endl; + else + res = true; + } else - res = true; + std::cerr << "CvCapture_OpenNI::setDepthGeneratorProperty : Unsupported viewpoint." << std::endl; } else - std::cerr << "CvCapture_OpenNI::setDepthGeneratorProperty : Unsupported viewpoint." << std::endl; + res = true; } else - res = true; + res = false; } else // "off" { @@ -460,30 +483,40 @@ bool CvCapture_OpenNI::setDepthGeneratorProperty( int propIdx, double propValue double CvCapture_OpenNI::getImageGeneratorProperty( int propIdx ) { - CV_Assert( imageGenerator.IsValid() ); - double res = 0; - switch( propIdx ) + + if (propIdx == CV_CAP_PROP_IMAGE_GENERATOR_PRESENT) + res = m_isImageGeneratorPresent ? 1 : -1; + else { - case CV_CAP_PROP_FRAME_WIDTH : - res = imageOutputMode.nXRes; - break; - case CV_CAP_PROP_FRAME_HEIGHT : - res = imageOutputMode.nYRes; - break; - case CV_CAP_PROP_FPS : - res = imageOutputMode.nFPS; - break; - default : - CV_Error( CV_StsBadArg, "Image generator does not support such parameter for getting.\n"); - } + if (!m_isImageGeneratorPresent) + return res; + CV_Assert( imageGenerator.IsValid() ); + + switch( propIdx ) + { + case CV_CAP_PROP_FRAME_WIDTH : + res = imageOutputMode.nXRes; + break; + case CV_CAP_PROP_FRAME_HEIGHT : + res = imageOutputMode.nYRes; + break; + case CV_CAP_PROP_FPS : + res = imageOutputMode.nFPS; + break; + default : + CV_Error( CV_StsBadArg, "Image generator does not support such parameter for getting.\n"); + } + } return res; } bool CvCapture_OpenNI::setImageGeneratorProperty( int propIdx, double propValue ) { bool res = false; + if(!m_isImageGeneratorPresent) + return res; CV_Assert( imageGenerator.IsValid() ); @@ -505,6 +538,11 @@ bool CvCapture_OpenNI::setImageGeneratorProperty( int propIdx, double propValue newImageOutputMode.nYRes = XN_SXGA_Y_RES; newImageOutputMode.nFPS = 15; break; + case CV_CAP_OPENNI_SXGA_30HZ : + newImageOutputMode.nXRes = XN_SXGA_X_RES; + newImageOutputMode.nYRes = XN_SXGA_Y_RES; + newImageOutputMode.nFPS = 30; + break; default : CV_Error( CV_StsBadArg, "Unsupported image generator output mode.\n"); } @@ -536,7 +574,8 @@ bool CvCapture_OpenNI::grabFrame() return false; depthGenerator.GetMetaData( depthMetaData ); - imageGenerator.GetMetaData( imageMetaData ); + if(m_isImageGeneratorPresent) + imageGenerator.GetMetaData( imageMetaData ); return true; } diff --git a/samples/cpp/kinect_maps.cpp b/samples/cpp/openni_capture.cpp similarity index 81% rename from samples/cpp/kinect_maps.cpp rename to samples/cpp/openni_capture.cpp index 280c6fd..9014fa7 100644 --- a/samples/cpp/kinect_maps.cpp +++ b/samples/cpp/openni_capture.cpp @@ -8,7 +8,7 @@ using namespace std; void help() { - cout << "\nThis program demonstrates usage of Kinect sensor.\n" + cout << "\nThis program demonstrates usage of depth sensors(Kinect,XtionPRO,...).\n" "The user gets some of the supported output images.\n" "\nAll supported output map types:\n" "1.) Data given from depth generator\n" @@ -88,19 +88,19 @@ void printCommandLineParams() { cout << "-cd Colorized disparity? (0 or 1; 1 by default) Ignored if disparity map is not selected to show." << endl; cout << "-fmd Fixed max disparity? (0 or 1; 0 by default) Ignored if disparity map is not colorized (-cd 0)." << endl; - cout << "-sxga SXGA resolution of image? (0 or 1; 0 by default) Ignored if rgb image or gray image are not selected to show." << endl; - cout << " If -sxga is 0 then vga resolution will be set by default." << endl; + cout << "-mode image mode: resolution and fps, supported three values: 0 - CV_CAP_OPENNI_VGA_30HZ, 1 - CV_CAP_OPENNI_SXGA_15HZ," << endl; + cout << " 2 - CV_CAP_OPENNI_SXGA_30HZ (0 by default). Ignored if rgb image or gray image are not selected to show." << endl; cout << "-m Mask to set which output images are need. It is a string of size 5. Each element of this is '0' or '1' and" << endl; cout << " determine: is depth map, disparity map, valid pixels mask, rgb image, gray image need or not (correspondently)?" << endl ; cout << " By default -m 01010 i.e. disparity map and rgb image will be shown." << endl ; } -void parseCommandLine( int argc, char* argv[], bool& isColorizeDisp, bool& isFixedMaxDisp, bool& isSetSXGA, bool retrievedImageFlags[] ) +void parseCommandLine( int argc, char* argv[], bool& isColorizeDisp, bool& isFixedMaxDisp, int& imageMode, bool retrievedImageFlags[] ) { // set defaut values isColorizeDisp = true; isFixedMaxDisp = false; - isSetSXGA = false; + imageMode = 0; retrievedImageFlags[0] = false; retrievedImageFlags[1] = true; @@ -129,9 +129,9 @@ void parseCommandLine( int argc, char* argv[], bool& isColorizeDisp, bool& isFix { isFixedMaxDisp = atoi(argv[++i]) == 0 ? false : true; } - else if( !strcmp( argv[i], "-sxga" ) ) + else if( !strcmp( argv[i], "-mode" ) ) { - isSetSXGA = atoi(argv[++i]) == 0 ? false : true; + imageMode = atoi(argv[++i]); } else if( !strcmp( argv[i], "-m" ) ) { @@ -164,16 +164,17 @@ void parseCommandLine( int argc, char* argv[], bool& isColorizeDisp, bool& isFix } /* - * To work with Kinect the user must install OpenNI library and PrimeSensorModule for OpenNI and + * To work with Kinect or XtionPRO the user must install OpenNI library and PrimeSensorModule for OpenNI and * configure OpenCV with WITH_OPENNI flag is ON (using CMake). */ int main( int argc, char* argv[] ) { - bool isColorizeDisp, isFixedMaxDisp, isSetSXGA; + bool isColorizeDisp, isFixedMaxDisp; + int imageMode; bool retrievedImageFlags[5]; - parseCommandLine( argc, argv, isColorizeDisp, isFixedMaxDisp, isSetSXGA, retrievedImageFlags ); + parseCommandLine( argc, argv, isColorizeDisp, isFixedMaxDisp, imageMode, retrievedImageFlags ); - cout << "Kinect opening ..." << endl; + cout << "Device opening ..." << endl; VideoCapture capture( CV_CAP_OPENNI ); cout << "done." << endl; @@ -183,22 +184,42 @@ int main( int argc, char* argv[] ) return -1; } - if( isSetSXGA ) - capture.set( CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_SXGA_15HZ ); - else - capture.set( CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_VGA_30HZ ); // default + bool modeRes; + switch ( imageMode ) + { + case 0: + modeRes = capture.set( CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_VGA_30HZ ); + break; + case 1: + modeRes = capture.set( CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_SXGA_15HZ ); + break; + case 2: + modeRes = capture.set( CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_SXGA_30HZ ); + break; + default: + CV_Error( CV_StsBadArg, "Unsupported image mode property.\n"); + } + if (!modeRes) + cout << "\nThis image mode is not supported by the device, the default value (CV_CAP_OPENNI_SXGA_15HZ) will be used.\n" << endl; - // Print some avalible Kinect settings. + // Print some avalible device settings. cout << "\nDepth generator output mode:" << endl << "FRAME_WIDTH " << capture.get( CV_CAP_PROP_FRAME_WIDTH ) << endl << "FRAME_HEIGHT " << capture.get( CV_CAP_PROP_FRAME_HEIGHT ) << endl << "FRAME_MAX_DEPTH " << capture.get( CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH ) << " mm" << endl << "FPS " << capture.get( CV_CAP_PROP_FPS ) << endl; - + bool isImageGeneratorPresent = capture.get( CV_CAP_OPENNI_PROP_IMAGE_GENERATOR_PRESENT ) > 0; + if (isImageGeneratorPresent) cout << "\nImage generator output mode:" << endl << "FRAME_WIDTH " << capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_WIDTH ) << endl << "FRAME_HEIGHT " << capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_HEIGHT ) << endl << "FPS " << capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FPS ) << endl; + else + { + cout << "\nDevice doesn't contain image generator" << endl; + if (!retrievedImageFlags[0] && !retrievedImageFlags[1] && !retrievedImageFlags[2]) + return 0; + } for(;;) { -- 2.7.4