【翻譯】Kinect v2程序設計(C++) Body 篇
Kinect SDK v1 | Kinect SDK v2預覽版 | |
---|---|---|
名稱 | Player | BodyIndex |
檢測支持人數 | 6人 | 6人 |
人體領域的値 | 1~6 | 0~5 |
非人體領域的値 | 0 | 255(0xff) |
Kinect SDK v2預覽版的主要功能的使用介紹,基本上完成了。這次,是關於取得Body(人體姿勢)方法的說明。
這一節,介紹從Kinect取得Body(人體姿勢)的方法。
Body
這個論文在IEEE CVPR 2011(計算機視覺及模式認識領域的首位會議)發表,獲獎Best Paper。
這個人體區域,在Kinect SDK v1被稱爲「Skeleton」,不過,在Kinect SDK v2預覽版裏更名爲「Body」。
// Sensor IKinectSensor* pSensor; ……1 HRESULT hResult = S_OK; hResult = GetDefaultKinectSensor( &pSensor ); ……2 if( FAILED( hResult ) ){ std::cerr << "Error : GetDefaultKinectSensor" << std::endl; return -1; } hResult = pSensor->Open(); ……3 if( FAILED( hResult ) ){ std::cerr << "Error : IKinectSensor::Open()" << std::endl; return -1; }
// Source IBodyFrameSource* pBodySource; ……1 hResult = pSensor->get_BodyFrameSource( &pBodySource ); ……2 if( FAILED( hResult ) ){ std::cerr << "Error : IKinectSensor::get_BodyFrameSource()" << std::endl; return -1; }
// Reader IBodyFrameReader* pBodyReader; ……1 hResult = pBodySource->OpenReader( &pBodyReader ); ……2 if( FAILED( hResult ) ){ std::cerr << "Error : IBodyFrameSource::OpenReader()" << std::endl; return -1; }
// Coordinate Mapper ICoordinateMapper* pCoordinateMapper; ……1 hResult = pSensor->get_CoordinateMapper( &pCoordinateMapper ); ……2 if( FAILED( hResult ) ){ std::cerr << "Error : IKinectSensor::get_CoordinateMapper()" << std::endl; return -1; }
int width = 1920; int height = 1080; unsigned int bufferSize = width * height * 4 * sizeof( unsigned char ); cv::Mat bufferMat( height, width, CV_8UC4 ); cv::Mat bodyMat( height / 2, width / 2, CV_8UC4 ); cv::namedWindow( "Body" ); // Color Table cv::Vec3b color[6]; color[0] = cv::Vec3b( 255, 0, 0 ); color[1] = cv::Vec3b( 0, 255, 0 ); color[2] = cv::Vec3b( 0, 0, 255 ); color[3] = cv::Vec3b( 255, 255, 0 ); color[4] = cv::Vec3b( 255, 0, 255 ); color[5] = cv::Vec3b( 0, 255, 255 ); while( 1 ){ // Color Frame ……1 IColorFrame* pColorFrame = nullptr; hResult = pColorReader->AcquireLatestFrame( &pColorFrame ); if( SUCCEEDED( hResult ) ){ hResult = pColorFrame->CopyConvertedFrameDataToArray( bufferSize, reinterpret_cast<BYTE*>( bufferMat.data ), ColorImageFormat_Bgra ); if( SUCCEEDED( hResult ) ){ cv::resize( bufferMat, bodyMat, cv::Size(), 0.5, 0.5 ); } } SafeRelease( pColorFrame ); /* Body部分在列表1.6 */ // Show Window cv::imshow( "Body", bodyMat ); if( cv::waitKey( 10 ) == VK_ESCAPE ){ break; } }
列表1.5,相當於圖1「Frame」,「Data」的部分(第1部分)
// Body Frame IBodyFrame* pBodyFrame = nullptr; ……1 hResult = pBodyReader->AcquireLatestFrame( &pBodyFrame ); ……2 if( SUCCEEDED( hResult ) ){ IBody* pBody[BODY_COUNT] = { 0 }; ……3 hResult = pBodyFrame->GetAndRefreshBodyData( BODY_COUNT, pBody ); ……3 if( SUCCEEDED( hResult ) ){ for( int count = 0; count < BODY_COUNT; count++ ){ BOOLEAN bTracked = false; ……4 hResult = pBody[count]->get_IsTracked( &bTracked ); ……4 if( SUCCEEDED( hResult ) && bTracked ){ Joint joint[JointType::JointType_Count]; ……5 hResult = pBody[count]->GetJoints( JointType::JointType_Count, joint ); ……5 if( SUCCEEDED( hResult ) ){ // Left Hand State HandState leftHandState = HandState::HandState_Unknown; ……6 hResult = pBody[count]->get_HandLeftState( &leftHandState ); ……6 if( SUCCEEDED( hResult ) ){ ColorSpacePoint colorSpacePoint = { 0 }; ……7 hResult = pCoordinateMapper->MapCameraPointToColorSpace( joint[JointType::JointType_HandLeft].Position, &colorSpacePoint ); ……7 if( SUCCEEDED( hResult ) ){ int x = static_cast<int>( colorSpacePoint.X ); int y = static_cast<int>( colorSpacePoint.Y ); if( ( x >= 0 ) && ( x < width ) && ( y >= 0 ) && ( y < height ) ){ if( leftHandState == HandState::HandState_Open ){ ……8 cv::circle( bufferMat, cv::Point( x, y ), 75, cv::Scalar( 0, 128, 0 ), 5, CV_AA ); } else if( leftHandState == HandState::HandState_Closed ){ ……8 cv::circle( bufferMat, cv::Point( x, y ), 75, cv::Scalar( 0, 0, 128 ), 5, CV_AA ); } else if( leftHandState == HandState::HandState_Lasso ){ ……8 cv::circle( bufferMat, cv::Point( x, y ), 75, cv::Scalar( 128, 128, 0 ), 5, CV_AA ); } } } } // Right Hand State /* 和左手一樣,獲取右手Hand State繪製狀態。 */ // Joint ……9 for( int type = 0; type < JointType::JointType_Count; type++ ){ ColorSpacePoint colorSpacePoint = { 0 }; pCoordinateMapper->MapCameraPointToColorSpace( joint[type].Position, &colorSpacePoint ); int x = static_cast< int >( colorSpacePoint.X ); int y = static_cast< int >( colorSpacePoint.Y ); if( ( x >= 0 ) && ( x < width ) && ( y >= 0 ) && ( y < height ) ){ cv::circle( bufferMat, cv::Point( x, y ), 5, static_cast<cv::Scalar>( color[count] ), -1, CV_AA ); } } } } } cv::resize( bufferMat, bodyMat, cv::Size(), 0.5, 0.5 ); } } SafeRelease( pBodyFrame );
Kinect SDK v1 | Kinect SDK v2預覽版 | |
---|---|---|
名稱 | Skeleton | Body |
人體姿勢可以取得的人數 | 2人 | 6人 |
Joint(關節) | 20處 | 25處 |
Hand State(手的狀態) | 2種類 | 3種類 |
Hand State可以取得的人數 | 2人 | 2人 |
圖4 Hand State的識別結果