2

我正在尝试使用带有 OpenNi 和 OpenCV 2.4 库的 kinect 来做一个用于指尖识别的 C++ 程序。

在这里我列出了我的主要功能(我故意避免在这里写下可能不是错误原因的其他功能/类):

// xml to initialize OpenNI
#define SAMPLE_XML_PATH "/home/jacopo/workspace/opencv_fingertip_detector/Sample-Tracking.xml"

int main(int argc, char ** argv)
{
    XnStatus rc = XN_STATUS_OK;
    xn::EnumerationErrors errors;

    // Initialize OpenNI
    rc = g_Context.InitFromXmlFile(SAMPLE_XML_PATH, g_ScriptNode, &errors);
    CHECK_ERRORS(rc, errors, "InitFromXmlFile");
    CHECK_RC(rc, "InitFromXmlFile");

    rc = g_Context.FindExistingNode(XN_NODE_TYPE_DEPTH, g_DepthGenerator);
    CHECK_RC(rc, "Find depth generator");
    rc = g_Context.FindExistingNode(XN_NODE_TYPE_HANDS, g_HandsGenerator);
    CHECK_RC(rc, "Find hands generator");
    rc = g_Context.FindExistingNode(XN_NODE_TYPE_GESTURE, g_GestureGenerator);
    CHECK_RC(rc, "Find gesture generator");

    XnCallbackHandle h;
    if (g_HandsGenerator.IsCapabilitySupported(XN_CAPABILITY_HAND_TOUCHING_FOV_EDGE))
    {
        g_HandsGenerator.GetHandTouchingFOVEdgeCap().RegisterToHandTouchingFOVEdge(TouchingCallback, NULL, h);
    }

    XnCallbackHandle hGestureIntermediateStageCompleted, hGestureProgress, hGestureReadyForNextIntermediateStage;
    g_GestureGenerator.RegisterToGestureIntermediateStageCompleted(GestureIntermediateStageCompletedHandler, NULL, hGestureIntermediateStageCompleted);
    g_GestureGenerator.RegisterToGestureReadyForNextIntermediateStage(GestureReadyForNextIntermediateStageHandler, NULL, hGestureReadyForNextIntermediateStage);
    g_GestureGenerator.RegisterGestureCallbacks(NULL, GestureProgressHandler, NULL, hGestureProgress);


    // Create NITE objects
    g_pSessionManager = new XnVSessionManager;
    rc = g_pSessionManager->Initialize(&g_Context, "Click,Wave", "RaiseHand");
    CHECK_RC(rc, "SessionManager::Initialize");

    g_pSessionManager->RegisterSession(NULL, SessionStarting, SessionEnding, FocusProgress);

    g_pDrawer = new XnVPointDrawer(20, g_DepthGenerator);
    g_pFlowRouter = new XnVFlowRouter;
    g_pFlowRouter->SetActive(g_pDrawer);

    g_pSessionManager->AddListener(g_pFlowRouter);

    g_pDrawer->RegisterNoPoints(NULL, NoHands);
    g_pDrawer->SetDepthMap(g_bDrawDepthMap);

    // Initialization done. Start generating
    rc = g_Context.StartGeneratingAll();
    CHECK_RC(rc, "StartGenerating");

    cv::Mat depthshow;
    int key_pre = 0 ;

    for( ; ; )
    {
        if (key_pre == 27)
            break ;
        XnMapOutputMode mode;
        g_DepthGenerator.GetMapOutputMode(mode);

        g_Context.WaitOneUpdateAll(g_DepthGenerator);

        //TEST
        g_DepthGenerator.GetMetaData(depthMD);
        XnDepthPixel* pDepth = depthMD.WritableData();

        // Update NITE tree
        g_pSessionManager->Update(&g_Context);

        if(g_pDrawer->handFound)
        {
            for (XnUInt y = 0; y < depthMD.YRes(); ++y)
            {
                for (XnUInt x = 0; x < depthMD.XRes(); ++x, ++pDepth)
                {

                    if (*pDepth>g_pDrawer->pt3D.Z+50 || *pDepth<g_pDrawer->pt3D.Z-50)
                    {
                        *pDepth=0;
                    }

                }
            }
        }

        //for opencv Mat
        cv::Mat depth16(480,640,CV_16SC1,(unsigned short*)depthMD.WritableData());

        //convert depth 11 bit image 2 8 bit image
        //depth16.convertTo(depthshow,CV_8U,-255/4096.0,255);
        depth16.convertTo(depthshow, CV_8UC1, 0.025);

        if(g_pDrawer->handFound)
        {
            cv::Point handPos(g_pDrawer->ptProjective.X, g_pDrawer->ptProjective.Y);
            cv::circle(depthshow, handPos, 5, cv::Scalar(0xffff), 10, 8, 0);
            Mat src_gray;
            int thresh = 10;
            RNG rng(12345);

            blur( depthshow, src_gray, Size(3,3) );

            Mat threshold_output;
            vector<vector<Point> > contours;
            vector<Vec4i> hierarchy;

            /// Detect edges using Threshold
            threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );

            /// Find contours
            findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

            /// Find the convex hull object for each contour
            vector<vector<int> > hullsI (contours.size());
            vector<vector<Point> >  hullsP (contours.size() );
            vector<vector<Vec4i> >  defects (contours.size() );

            for( int i = 0; i < contours.size(); i++ )
            {
                convexHull(contours[i], hullsI[i], false, false);
                convexHull(contours[i], hullsP[i], false, true);
                if (contours[i].size() >3 )
                {
                    convexityDefects(contours[i], hullsI[i], defects[i]);
                }
            }

            /// Draw contours + hull results
            Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );

            for( int i = 0; i < defects.size(); i++)
            {
                Vec4i defect(defects[i][0]);
                Point start = contours[i][defect[0]];
                Point end = contours[i][defect[1]];
                Point far = contours[i][defect[2]];
                std::cout << "Roba mia: "<< start << "\t" << end << "\t" << far << std::endl;
                line(drawing, start, end, Scalar( 255, 0, 0 ), 1);
                circle(drawing, far, 5, Scalar( 255, 0, 0 ), 1);
            }

            for( int i = 0; i < contours.size(); i++ )
            {
                Scalar color = Scalar( 255, 0, 0 );
                drawContours( drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
                drawContours( drawing, hullsP, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
            }

            /// Show in a window
            namedWindow( "Hull demo", CV_WINDOW_AUTOSIZE );
            imshow( "Hull demo", drawing );

        }

        cv::imshow("PrimeSense Nite Point Viewer", depthshow);
        key_pre = cv::waitKey(33);

    }
    cv::destroyWindow("PrimeSense Nite Point Viewer");
    CleanupExit();
    return 0;
}

当我尝试使用其中一个变量时会发生分段错误startend或者far,如果我在分配三个变量后立即注释三行(和) std::cout,则代码正常运行而没有问题。linecircle

你们中有人知道如何解决这个问题吗?

谢谢阅读

J。

4

0 回答 0