я пытаюсь сделать C ++ программу для распознавания кончиков пальцев, используя kinect с библиотеками OpenNi и OpenCV 2.4.
Здесь я перечислю свою основную функцию (я намеренно избегал записывать здесь другие функции / классы, которые, вероятно, не являются причиной ошибки):
// 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;
}
Ошибка сегментации происходит, когда я пытаюсь использовать одну из переменных start
, end
или же far
действительно, если я прокомментирую три строки (std::cout
, line
а также circle
) сразу после того, как я назначил три переменные, код работает нормально без проблем.
У кого-нибудь из вас есть идея, как решить эту проблему?
Спасибо за прочтение
J.
Задача ещё не решена.
Других решений пока нет …