added ability to get and set some Kinect params

pull/13383/head
Maria Dimashova 14 years ago
parent ee74e2cf08
commit 508aaa41f8
  1. 26
      modules/highgui/include/opencv2/highgui/highgui_c.h
  2. 171
      modules/highgui/src/cap_openni.cpp
  3. 50
      samples/cpp/kinect_maps.cpp

@ -383,6 +383,32 @@ enum
OPENNI_GRAY_IMAGE = 6
};
// OpenNI map generators
enum
{
OPENNI_DEPTH_GENERATOR = 0,
OPENNI_IMAGE_GENERATOR = 1 << 31
};
// Properties of Kinect (additional to ones begining from CV_CAP_PROP_...)
enum
{
OPENNI_OUTPUT_MODE = 20,
OPENNI_FRAME_MAX_DEPTH = 21, // in mm
OPENNI_BASELINE = 22, // in mm
OPENNI_FOCAL_LENGTH = 23, // in pixels
OPENNI_IMAGE_GENERATOR_OUTPUT_MODE = OPENNI_IMAGE_GENERATOR + OPENNI_OUTPUT_MODE,
OPENNI_DEPTH_GENERATOR_BASELINE = OPENNI_DEPTH_GENERATOR + OPENNI_BASELINE,
OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH = OPENNI_DEPTH_GENERATOR + OPENNI_FOCAL_LENGTH
};
// Supported output modes of OpenNI image generator
enum
{
OPENNI_VGA_30HZ = 0,
OPENNI_SXGA_15HZ = 1
};
const int OPENNI_BAD_DEPTH_VAL = 0;
const int OPENNI_BAD_DISP_VAL = 0;

@ -119,6 +119,11 @@ protected:
void readCamerasParams();
double getDepthGeneratorProperty(int);
bool setDepthGeneratorProperty(int, double);
double getImageGeneratorProperty(int);
bool setImageGeneratorProperty(int, double);
// OpenNI context
xn::Context context;
bool m_isOpened;
@ -126,9 +131,11 @@ protected:
// Data generators with its metadata
xn::DepthGenerator depthGenerator;
xn::DepthMetaData depthMetaData;
XnMapOutputMode depthOutputMode;
xn::ImageGenerator imageGenerator;
xn::ImageMetaData imageMetaData;
XnMapOutputMode imageOutputMode;
// Cameras settings:
#if 1
@ -163,13 +170,16 @@ CvCapture_OpenNI::CvCapture_OpenNI()
{
XnStatus status = XN_STATUS_OK;
// Initialize the context with default configuration.
status = context.Init();
m_isOpened = (status == XN_STATUS_OK);
// Initialize image output modes (VGA_30HZ by default).
depthOutputMode.nXRes = imageOutputMode.nXRes = XN_VGA_X_RES;
depthOutputMode.nYRes = imageOutputMode.nYRes = XN_VGA_Y_RES;
depthOutputMode.nFPS = imageOutputMode.nFPS = 30;
if( m_isOpened )
m_isOpened = false;
// Initialize and configure the context.
if( context.Init() == XN_STATUS_OK )
{
// Configure the context.
#ifdef HACK_WITH_XML
// Write configuration to the temporary file.
// This is a hack, because there is a bug in RunXmlScript().
@ -187,10 +197,12 @@ CvCapture_OpenNI::CvCapture_OpenNI()
#else
status = context.RunXmlScript( XMLConfig.c_str() );
#endif
if( status != XN_STATUS_OK )
CV_Error(CV_StsError, ("Failed to apply XML configuration: " + std::string(xnGetStatusString(status))).c_str() );
m_isOpened = ( status == XN_STATUS_OK );
}
// Initialize generators.
if( m_isOpened )
{
// Associate generators with context.
status = depthGenerator.Create( context );
if( status != XN_STATUS_OK )
CV_Error(CV_StsError, ("Failed to create depth generator: " + std::string(xnGetStatusString(status))).c_str() );
@ -198,6 +210,10 @@ CvCapture_OpenNI::CvCapture_OpenNI()
if( status != XN_STATUS_OK )
CV_Error(CV_StsError, ("Failed to create image generator: " + std::string(xnGetStatusString(status))).c_str() );
// 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 );
// Start generating data.
status = context.StartGeneratingAll();
if( status != XN_STATUS_OK )
@ -247,18 +263,141 @@ void CvCapture_OpenNI::readCamerasParams()
CV_Error( CV_StsError, "Could not read no sample value!" );
}
double CvCapture_OpenNI::getProperty(int)
double CvCapture_OpenNI::getProperty( int propIdx )
{
assert(0);
// TODO
return 0;
double propValue = -1;
if( isOpened() )
{
if( propIdx & OPENNI_IMAGE_GENERATOR )
{
propValue = getImageGeneratorProperty( propIdx ^ OPENNI_IMAGE_GENERATOR );
}
else // depth generator (by default, OPENNI_DEPTH_GENERATOR == 0)
{
propValue = getDepthGeneratorProperty( propIdx /*^ OPENNI_DEPTH_GENERATOR*/ );
}
}
return propValue;
}
bool CvCapture_OpenNI::setProperty(int, double)
bool CvCapture_OpenNI::setProperty( int propIdx, double propValue )
{
assert(0);
// TODO
return true;
bool res = false;
if( isOpened() )
{
if( propIdx & OPENNI_IMAGE_GENERATOR )
{
res = setImageGeneratorProperty( propIdx ^ OPENNI_IMAGE_GENERATOR, propValue );
}
else // depth generator (by default, OPENNI_DEPTH_GENERATOR == 0)
{
res = setDepthGeneratorProperty( propIdx /*^ OPENNI_DEPTH_GENERATOR*/, propValue );
}
}
return false;
}
double CvCapture_OpenNI::getDepthGeneratorProperty( int propIdx )
{
CV_Assert( depthGenerator.IsValid() );
double res = -1;
switch( propIdx )
{
case CV_CAP_PROP_FRAME_WIDTH :
res = depthOutputMode.nXRes;
break;
case CV_CAP_PROP_FRAME_HEIGHT :
res = depthOutputMode.nYRes;
break;
case CV_CAP_PROP_FPS :
res = depthOutputMode.nFPS;
break;
case OPENNI_FRAME_MAX_DEPTH :
res = depthGenerator.GetDeviceMaxDepth();
break;
case OPENNI_BASELINE :
res = baseline;
break;
case OPENNI_FOCAL_LENGTH :
res = depthFocalLength_VGA;
break;
default :
CV_Error( CV_StsBadArg, "Depth generator does not support such parameter for getting.\n");
}
return res;
}
bool CvCapture_OpenNI::setDepthGeneratorProperty( int propIdx, double propValue )
{
CV_Assert( depthGenerator.IsValid() );
CV_Error( CV_StsBadArg, "Depth generator does not support such parameter for setting.\n");
}
double CvCapture_OpenNI::getImageGeneratorProperty( int propIdx )
{
CV_Assert( imageGenerator.IsValid() );
double res = -1;
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;
CV_Assert( imageGenerator.IsValid() );
XnMapOutputMode newImageOutputMode = imageOutputMode;
switch( propIdx )
{
case OPENNI_OUTPUT_MODE :
switch( cvRound(propValue) )
{
case OPENNI_VGA_30HZ :
newImageOutputMode.nXRes = XN_VGA_X_RES;
newImageOutputMode.nYRes = XN_VGA_Y_RES;
newImageOutputMode.nFPS = 30;
break;
case OPENNI_SXGA_15HZ :
newImageOutputMode.nXRes = XN_SXGA_X_RES;
newImageOutputMode.nYRes = XN_SXGA_Y_RES;
newImageOutputMode.nFPS = 15;
break;
default :
CV_Error( CV_StsBadArg, "Unsupported image generator output mode.\n");
}
break;
default:
CV_Error( CV_StsBadArg, "Image generator does not support such parameter for setting.\n");
}
if( imageGenerator.SetMapOutputMode( newImageOutputMode ) == XN_STATUS_OK )
{
imageOutputMode = newImageOutputMode;
res = true;
}
return res;
}
bool CvCapture_OpenNI::grabFrame()

@ -6,14 +6,20 @@
using namespace cv;
using namespace std;
void colorizeDisparity( const Mat& gray, Mat& rgb, float S=1.f, float V=1.f )
#define COLORIZED_DISP 1
#define IMAGE_GENERATOR_VGA_30HZ 1
#define FIXED_MAX_DISP 0
void colorizeDisparity( const Mat& gray, Mat& rgb, double maxDisp=-1.f, float S=1.f, float V=1.f )
{
CV_Assert( !gray.empty() );
CV_Assert( gray.type() == CV_8UC1 );
// TODO do maxDisp constant (when camera properties will be accessible)
double maxDisp = 0;
if( maxDisp <= 0 )
{
maxDisp = 0;
minMaxLoc( gray, 0, &maxDisp );
}
rgb.create( gray.size(), CV_8UC3 );
for( int y = 0; y < gray.rows; y++ )
@ -70,6 +76,18 @@ void help()
<< endl;
}
float getMaxDisparity( VideoCapture& capture )
{
#if FIXED_MAX_DISP
const int minDistance = 400; // mm
float b = capture.get( OPENNI_DEPTH_GENERATOR_BASELINE ); // mm
float F = capture.get( OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH ); // pixels
return b * F / minDistance;
#else
return -1;
#endif
}
/*
* To work with Kinect the user must install OpenNI library and PrimeSensorModule for OpenNI and
* configure OpenCV with WITH_OPENNI flag is ON (using CMake).
@ -88,6 +106,24 @@ int main()
return -1;
}
#if IMAGE_GENERATOR_VGA_30HZ
capture.set( OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, OPENNI_VGA_30HZ ); // default
#else
capture.set( OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, OPENNI_SXGA_15HZ );
#endif
// Print some avalible Kinect settings.
cout << "Depth 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( OPENNI_FRAME_MAX_DEPTH ) << " mm" << endl <<
"FPS " << capture.get( CV_CAP_PROP_FPS ) << endl;
cout << "Image generator output mode:" << endl <<
"FRAME_WIDTH " << capture.get( OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_WIDTH ) << endl <<
"FRAME_HEIGHT " << capture.get( OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FRAME_HEIGHT ) << endl <<
"FPS " << capture.get( OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FPS ) << endl;
for(;;)
{
Mat depthMap;
@ -112,14 +148,14 @@ int main()
if( capture.retrieve( disparityMap, OPENNI_DISPARITY_MAP ) )
{
#if 0 // original disparity
imshow( "original disparity map", disparityMap );
#else // colorized disparity for more visibility
#if COLORIZED_DISP // colorized disparity for more visibility
Mat colorDisparityMap;
colorizeDisparity( disparityMap, colorDisparityMap );
colorizeDisparity( disparityMap, colorDisparityMap, getMaxDisparity( capture ) );
Mat validColorDisparityMap;
colorDisparityMap.copyTo( validColorDisparityMap, disparityMap != OPENNI_BAD_DISP_VAL );
imshow( "colorized disparity map", validColorDisparityMap );
#else // original disparity
imshow( "original disparity map", disparityMap );
#endif
}

Loading…
Cancel
Save