Esempio n. 1
0
int main (int argc, char * argv[])
{
    IplImage* camera = 0;
    
    try {
        // コンテキストの初期化
        xn::Context context;
        XnStatus rc = context.InitFromXmlFile(CONFIG_XML_PATH);
        if (rc != XN_STATUS_OK) {
            throw std::runtime_error(xnGetStatusString(rc));
        }
        
        // 鏡モード(反転)にする
        context.SetGlobalMirror(TRUE);
        
        // イメージジェネレータの作成
        xn::ImageGenerator image;
        rc = context.FindExistingNode(XN_NODE_TYPE_IMAGE, image);
        if (rc != XN_STATUS_OK) {
            throw std::runtime_error(xnGetStatusString(rc));
        }
        
        // デプスジェネレータの作成
        xn::DepthGenerator depth;
        rc = context.FindExistingNode(XN_NODE_TYPE_DEPTH, depth);
        if (rc != XN_STATUS_OK) {
            throw std::runtime_error(xnGetStatusString(rc));
        }
        
        // デプスの座標をイメージに合わせる
        depth.GetAlternativeViewPointCap().SetViewPoint(image);
        
        // ユーザーの作成
        xn::UserGenerator user;
        rc = context.FindExistingNode( XN_NODE_TYPE_USER, user );
        if ( rc != XN_STATUS_OK ) {
            rc = user.Create(context);
            if ( rc != XN_STATUS_OK ) {
                throw std::runtime_error( xnGetStatusString( rc ) );
            }
        }
        
        // ユーザー検出機能をサポートしているか確認
        if (!user.IsCapabilitySupported(XN_CAPABILITY_SKELETON)) {
            throw std::runtime_error("ユーザー検出をサポートしてません");
        }
        
        XnCallbackHandle userCallbacks, calibrationCallbacks, poseCallbacks;
        XnChar pose[20] = "";
        
        // キャリブレーションにポーズが必要
        xn::SkeletonCapability skelton = user.GetSkeletonCap();
        if (skelton.NeedPoseForCalibration()) {
            // ポーズ検出のサポートチェック
            if (!user.IsCapabilitySupported(XN_CAPABILITY_POSE_DETECTION)) {
                throw std::runtime_error("ポーズ検出をサポートしてません");
            }
            
            // キャリブレーションポーズの取得
            skelton.GetCalibrationPose(pose);
            
            // ポーズ検出のコールバックを登録
            xn::PoseDetectionCapability pose = user.GetPoseDetectionCap();
            pose.RegisterToPoseCallbacks(&::PoseDetected, &::PoseLost,
                                         &user, poseCallbacks);
        }
        
        // ユーザー認識のコールバックを登録
        user.RegisterUserCallbacks(&::UserDetected, &::UserLost, pose,
                                   userCallbacks);
        
        // キャリブレーションのコールバックを登録
        skelton.RegisterCalibrationCallbacks(&::CalibrationStart, &::CalibrationEnd,
                                             &user, calibrationCallbacks);
        
        // ユーザートラッキングで、すべてをトラッキングする
        skelton.SetSkeletonProfile(XN_SKEL_PROFILE_ALL);
        
        // ジェスチャー検出の開始
        context.StartGeneratingAll();
        
        // カメラサイズのイメージを作成(8bitのRGB)
        XnMapOutputMode outputMode;
        image.GetMapOutputMode(outputMode);
        camera = ::cvCreateImage(cvSize(outputMode.nXRes, outputMode.nYRes),
                                 IPL_DEPTH_8U, 3);
        if (!camera) {
            throw std::runtime_error("error : cvCreateImage");
        }
        
        // 表示状態
        bool isShowImage = true;
        bool isShowUser = true;
        bool isShowSkelton = true;
        

        // 描画状態
        static enum State{
            IDLE = 0,
            CIRCLE,
        } state[15] = { IDLE };

        typedef std::vector<XnPoint3D> line;
        line points;
        CvScalar color = CV_RGB(0,0,0);
        
        typedef std::vector<CvScalar> LineColors;
        LineColors colors;
        colors.push_back(CV_RGB(255,255,255));
        colors.push_back(CV_RGB(255,255,255));
        colors.push_back(CV_RGB(0,0,0));
        colors.push_back(CV_RGB(255,0,0));
        colors.push_back(CV_RGB(0,255,0));
        colors.push_back(CV_RGB(0,0,255));
        colors.push_back(CV_RGB(255,255,0));
        colors.push_back(CV_RGB(0,255,255));
        colors.push_back(CV_RGB(255,0,255));
        
        // メインループ
        while (1) {
            // すべてのノードの更新を待つ
            context.WaitAndUpdateAll();
            
            // 画像データの取得
            xn::ImageMetaData imageMD;
            image.GetMetaData(imageMD);
            
            // ユーザーデータの取得
            xn::SceneMetaData sceneMD;
            user.GetUserPixels(0, sceneMD);
            
            // カメラ画像の表示
            char* dest = camera->imageData;
            const xn::RGB24Map& rgb = imageMD.RGB24Map();
            for (int y = 0; y < imageMD.YRes(); ++y) {
                for (int x = 0; x < imageMD.XRes(); ++x) {
                    // ユーザー表示
                    XnLabel label = sceneMD(x, y);
                    if (!isShowUser) {
                        label = 0;
                    }
                    
                    // カメラ画像の表示
                    XnRGB24Pixel pixel = rgb(x, y);
                    if (!isShowImage) {
                        pixel = xnRGB24Pixel( 255, 255, 255 );
                    }
                    
                    // 出力先に描画
                    dest[0] = pixel.nRed   * Colors[label][0];
                    dest[1] = pixel.nGreen * Colors[label][1];
                    dest[2] = pixel.nBlue  * Colors[label][2];
                    dest += 3;
                }
            }
            
            // スケルトンの描画
            if (isShowSkelton) {
                XnUserID aUsers[15];
                XnUInt16 nUsers = 15;
                user.GetUsers(aUsers, nUsers);
//                for (int i = 0; i < nUsers; ++i) {
                for (int i = 0; i < 1; ++i) {
                    if (skelton.IsTracking(aUsers[i])) {
                        SkeltonDrawer skeltonDrawer(camera, skelton,
                                                    depth, aUsers[i]);
                        skeltonDrawer.draw();

                        // 右手と右肩の距離を表示
                        XnSkeletonJointPosition shoulder, l_shoulder, r_hand, l_hand;
                        skelton.GetSkeletonJointPosition(aUsers[i], XN_SKEL_RIGHT_SHOULDER, shoulder);
                        skelton.GetSkeletonJointPosition(aUsers[i], XN_SKEL_RIGHT_HAND, r_hand);
                        skelton.GetSkeletonJointPosition(aUsers[i], XN_SKEL_LEFT_SHOULDER, l_shoulder);
                        skelton.GetSkeletonJointPosition(aUsers[i], XN_SKEL_LEFT_HAND, l_hand);

                        // 現実の座標を画面座標に変換する
                        XnPoint3D pt_r_hand, pt_l_hand;
                        depth.ConvertRealWorldToProjective(1, &r_hand.position, &pt_r_hand);
                        depth.ConvertRealWorldToProjective(1, &l_hand.position, &pt_l_hand);

                        // 右肩と右手の間隔が40cm以上(手を前に出してる感じ)
                        if ((shoulder.position.Z - r_hand.position.Z) >= 400) {
                            std::cout << " CIRCLE";
                            state[i] = CIRCLE;
                        }
                        // 右肩と右手の間隔が40cm以上(手を前に出してる感じ)
                        if ((l_shoulder.position.Z - l_hand.position.Z) >= 400) {
                            std::cout << " IDLE";
                            state[i] = IDLE;
                        }
                        
                        
                        // 左上に左手を持ってたら色を変える
                        int r = 50;
                        for (int c = 0; c < colors.size(); ++c) {
                            cvRectangle(camera, cvPoint(c * r, 0), cvPoint((c+1)*r, r), colors[c], CV_FILLED);
                        }
                        if (pt_l_hand.Y < r) {
                            int index = pt_l_hand.X / r;
                            if (index == 0) {
                                points.clear();
                            }
                            else if (index < colors.size()) {
                                std::cout << " change color";
                                color = colors[index];
                            }
                        }
                        
                        std::cout << std::endl;

                        if (state[i] == CIRCLE) {
                            points.push_back(pt_r_hand);
                            cvCircle(camera, cvPoint(pt_r_hand.X, pt_r_hand.Y), 10, CV_RGB(255, 255, 0), 5);
                        }

                        // 線を書く
                        for (line::iterator it = points.begin();it != points.end();){
                            CvPoint pt1 = cvPoint(it->X, it->Y);
                            CvPoint pt2 = cvPoint(it->X, it->Y);
                            if (++it != points.end()) {
                                pt2 = cvPoint(it->X, it->Y);
                            }
                            
                            ::cvLine(camera, pt1, pt2, color, 3);
                        }
                    }
                }
            }
            
            ::cvCvtColor(camera, camera, CV_BGR2RGB);
            ::cvShowImage("KinectImage", camera);
            
            // キーイベント
            char key = cvWaitKey(10);
            // 終了する
            if (key == 'q') {
                break;
            }
            // 反転する
            else if (key == 'm') {
                context.SetGlobalMirror(!context.GetGlobalMirror());
            }
            // 表示する/しないの切り替え
            else if (key == 'i') {
                isShowImage = !isShowImage;
            }
            else if (key == 'u') {
                isShowUser = !isShowUser;
            }
            else if (key == 's') {
                isShowSkelton = !isShowSkelton;
            }
        }
    }
    catch (std::exception& ex) {
        std::cout << ex.what() << std::endl;
    }
    
    ::cvReleaseImage(&camera);
    
    return 0;
}
Esempio n. 2
0
int main (int argc, char * argv[])
{

    try {
        // コンテキストの初期化
        xn::Context context;
        XnStatus rc = context.InitFromXmlFile(CONFIG_XML_PATH);
        if (rc != XN_STATUS_OK) {
            throw std::runtime_error(xnGetStatusString(rc));
        }

        // イメージジェネレータの作成
        xn::ImageGenerator image;
        rc = context.FindExistingNode(XN_NODE_TYPE_IMAGE, image);
        if (rc != XN_STATUS_OK) {
            throw std::runtime_error(xnGetStatusString(rc));
        }

        // デプスジェネレータの作成
        xn::DepthGenerator depth;
        rc = context.FindExistingNode(XN_NODE_TYPE_DEPTH, depth);
        if (rc != XN_STATUS_OK) {
            throw std::runtime_error(xnGetStatusString(rc));
        }

        // デプスの座標をイメージに合わせる
        depth.GetAlternativeViewPointCap().SetViewPoint(image);

        // ユーザーの作成
        xn::UserGenerator user;
        rc = context.FindExistingNode( XN_NODE_TYPE_USER, user );
        if ( rc != XN_STATUS_OK ) {
            rc = user.Create(context);
            if ( rc != XN_STATUS_OK ) {
                throw std::runtime_error( xnGetStatusString( rc ) );
            }
        }

        // ユーザー検出機能をサポートしているか確認
        if (!user.IsCapabilitySupported(XN_CAPABILITY_SKELETON)) {
            throw std::runtime_error("ユーザー検出をサポートしてません");
        }

        XnCallbackHandle userCallbacks, calibrationCallbacks, poseCallbacks;
        XnChar pose[20] = "";

        // キャリブレーションにポーズが必要
        xn::SkeletonCapability skelton = user.GetSkeletonCap();
        if (skelton.NeedPoseForCalibration()) {
            // ポーズ検出のサポートチェック
            if (!user.IsCapabilitySupported(XN_CAPABILITY_POSE_DETECTION)) {
                throw std::runtime_error("ポーズ検出をサポートしてません");
            }

            // キャリブレーションポーズの取得
            skelton.GetCalibrationPose(pose);

            // ポーズ検出のコールバックを登録
            xn::PoseDetectionCapability pose = user.GetPoseDetectionCap();
            pose.RegisterToPoseCallbacks(&::PoseDetected, &::PoseLost,
                &user, poseCallbacks);
        }

        // ユーザー認識のコールバックを登録
        user.RegisterUserCallbacks(&::UserDetected, &::UserLost, pose, userCallbacks);

        // キャリブレーションのコールバックを登録
        skelton.RegisterCalibrationCallbacks(&::CalibrationStart, &::CalibrationEnd,
            &user, calibrationCallbacks);

        // ユーザートラッキングで、すべてをトラッキングする
        skelton.SetSkeletonProfile(XN_SKEL_PROFILE_ALL);

        // ジェスチャー検出の開始
        context.StartGeneratingAll();

        // カメラサイズのイメージを作成(8bitのRGB)
        XnMapOutputMode outputMode;
        image.GetMapOutputMode(outputMode);
        cv::Ptr< IplImage > camera = ::cvCreateImage(cvSize(outputMode.nXRes, outputMode.nYRes), IPL_DEPTH_8U, 3);
        if (!camera) {
            throw std::runtime_error("error : cvCreateImage");
        }

        // メインループ
        while (1) {
            // すべてのノードの更新を待つ
            context.WaitAndUpdateAll();

            // 画像データの取得
            xn::ImageMetaData imageMD;
            image.GetMetaData(imageMD);

            // ユーザーデータの取得
            xn::SceneMetaData sceneMD;
            user.GetUserPixels(0, sceneMD);

            // カメラ画像の表示
            char* dest = camera->imageData;
            const xn::RGB24Map& rgb = imageMD.RGB24Map();
            for (int y = 0; y < imageMD.YRes(); ++y) {
                for (int x = 0; x < imageMD.XRes(); ++x) {
                    // ユーザー表示
                    XnLabel label = sceneMD(x, y);

                    // カメラ画像の表示
                    XnRGB24Pixel pixel = rgb(x, y);
                    pixel = xnRGB24Pixel( 255, 255, 255 );

                    // 出力先に描画
                    dest[0] = pixel.nRed   * Colors[label][0];
                    dest[1] = pixel.nGreen * Colors[label][1];
                    dest[2] = pixel.nBlue  * Colors[label][2];
                    dest += 3;
                }
            }

            // スケルトンの描画
            XnUserID aUsers[15];
            XnUInt16 nUsers = 15;
            user.GetUsers(aUsers, nUsers);
            for (int i = 0; i < nUsers; ++i) {
                if (skelton.IsTracking(aUsers[i])) {
                    SkeltonDrawer skeltonDrawer(camera, skelton,
                        depth, aUsers[i]);
                    skeltonDrawer.draw();
                }
            }

            ::cvCvtColor(camera, camera, CV_BGR2RGB);
            ::cvShowImage("KinectImage", camera);

            // キーイベント
            char key = cvWaitKey(10);
            // 終了する
            if (key == 'q') {
                break;
            }
        }
    }
    catch (std::exception& ex) {
        std::cout << ex.what() << std::endl;
    }

    return 0;
}