added support of Asus XtionPRO (thanks to Gustav Karlsson for his patches) #1657
authorAlexander Shishkov <no@email>
Mon, 12 Mar 2012 16:07:42 +0000 (16:07 +0000)
committerAlexander Shishkov <no@email>
Mon, 12 Mar 2012 16:07:42 +0000 (16:07 +0000)
modules/highgui/include/opencv2/highgui/highgui_c.h
modules/highgui/src/cap_openni.cpp
samples/cpp/openni_capture.cpp [moved from samples/cpp/kinect_maps.cpp with 81% similarity]

index c2adf70..d23b0b2 100644 (file)
@@ -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
index c470be7..2a16a1c 100644 (file)
@@ -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 =
                 "</Dumps>"
         "</Log>"
         "<ProductionNodes>"
-                "<Node type=\"Image\" name=\"Image1\">"
+                "<Node type=\"Image\" name=\"Image1\" stopOnError=\"false\">"
                         "<Configuration>"
                                 "<MapOutputMode xRes=\"640\" yRes=\"480\" FPS=\"30\"/>"
                                 "<Mirror on=\"false\"/>"
@@ -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;
 }
 
similarity index 81%
rename from samples/cpp/kinect_maps.cpp
rename to samples/cpp/openni_capture.cpp
index 280c6fd..9014fa7 100644 (file)
@@ -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(;;)
     {