2011-01-19 38 views
1

我使用從項目的代碼FingertipTuio3DOpenCV的向量訪問錯誤

std::vector<cv::Point2i> detectFingertips(cv::Mat1f z, float zMin = 0.0f, float zMax = 0.75f, cv::Mat1f& debugFrame = cv::Mat1f()) { 
    using namespace cv; 
    using namespace std;  
    bool debug = !debugFrame.empty(); 

    vector<Point2i> fingerTips; 

    Mat handMask = z < zMax & z > zMin; 

    std::vector<std::vector<cv::Point>> contours; 
    findContours(handMask.clone(), contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE); // we are cloning here since method will destruct the image 

    if (contours.size()) { 
     for (int i=0; i<contours.size(); i++) { 
      vector<Point> contour = contours[i]; 
      Mat contourMat = Mat(contour); 
      double area = cv::contourArea(contourMat); 

      if (area > 3000) { // possible hand 
       Scalar center = mean(contourMat); 
       Point centerPoint = Point(center.val[0], center.val[1]); 

       vector<Point> approxCurve; 
       cv::approxPolyDP(contourMat, approxCurve, 20, true); 

       vector<int> hull; 
       cv::convexHull(Mat(approxCurve), hull); 

       // find upper and lower bounds of the hand and define cutoff threshold (don't consider lower vertices as fingers) 
       int upper = 640, lower = 0; 
       for (int j=0; j<hull.size(); j++) { 
        int idx = hull[j]; // corner index 
        if (approxCurve[idx].y < upper) upper = approxCurve[idx].y; 
        if (approxCurve[idx].y > lower) lower = approxCurve[idx].y; 
       } 
       float cutoff = lower - (lower - upper) * 0.1f; 

       // find interior angles of hull corners 
       for (int j=0; j<hull.size(); j++) { 
        int idx = hull[j]; // corner index 
        int pdx = idx == 0 ? approxCurve.size() - 1 : idx - 1; // predecessor of idx 
        int sdx = idx == approxCurve.size() - 1 ? 0 : idx + 1; // successor of idx 

        Point v1 = approxCurve[sdx] - approxCurve[idx]; 
        Point v2 = approxCurve[pdx] - approxCurve[idx]; 

        float angle = acos((v1.x*v2.x + v1.y*v2.y)/(norm(v1) * norm(v2))); 

        // low interior angle + within upper 90% of region -> we got a finger 
        if (angle < 1 && approxCurve[idx].y < cutoff) { 
         int u = approxCurve[idx].x; 
         int v = approxCurve[idx].y; 

         fingerTips.push_back(Point2i(u,v)); 

         if (debug) { 
          cv::circle(debugFrame, approxCurve[idx], 10, Scalar(1), -1); 
         } 
        } 
       } 

       if (debug) { 
        // draw cutoff threshold 
        cv::line(debugFrame, Point(center.val[0]-100, cutoff), Point(center.val[0]+100, cutoff), Scalar(1.0f)); 

        // draw approxCurve 
        for (int j=0; j<approxCurve.size(); j++) { 
         cv::circle(debugFrame, approxCurve[j], 10, Scalar(1.0f)); 
         if (j != 0) { 
          cv::line(debugFrame, approxCurve[j], approxCurve[j-1], Scalar(1.0f)); 
         } else { 
          cv::line(debugFrame, approxCurve[0], approxCurve[approxCurve.size()-1], Scalar(1.0f)); 
         } 
        } 

        // draw approxCurve hull 
        for (int j=0; j<hull.size(); j++) { 
         cv::circle(debugFrame, approxCurve[hull[j]], 10, Scalar(1.0f), 3); 
         if(j == 0) { 
          cv::line(debugFrame, approxCurve[hull[j]], approxCurve[hull[hull.size()-1]], Scalar(1.0f)); 
         } else { 
          cv::line(debugFrame, approxCurve[hull[j]], approxCurve[hull[j-1]], Scalar(1.0f)); 
         } 
        } 
       } 
      } 
     } 
    } 

    return fingerTips; 
} 

當代碼到達該點vector<Point> contour = contours[i];失敗與AccessViolation:在 FingertipTuio3d在0x00b85039

未處理的異常。 exe:0xC0000005: 訪問衝突讀取位置 0x00000008。

該位置在std :: vector的size_type size() const函數中。

任何想法是什麼導致問題,以及如何解決它?

+0

什麼是原型`findContours`? – 2011-01-19 20:51:31

+0

`CV_EXPORTS void findContours(Mat&image,vector >&contours, int mode,int method,Point offset = Point());` – Malfist 2011-01-19 20:53:10

+0

那麼,那就是假設。 – 2011-01-19 20:55:55

回答

0

您的findContours實際上是否將任何東西放入每個輪廓?

您檢查數組存在,但不是單獨的元素是有效的

0

您可以通過迭代器訪問元素? IOW,如果在loadContours的調用之後立即添加以下代碼,您會得到什麼輸出?

int i = 0; 
for (std::vector<std::vector<cv::Point> >::iterator it = contours.begin(); 
    it != contours.end(); 
    ++it) 
{ 
    std::cout << "contours[" << i << "].size() == " << it->size() << std::endl; 
} 
0

因爲輪廓是矢量的矢量(標準::矢量>輪廓;)

和輪廓是一個點的矢量(矢量輪廓)

所以它不能做矢量輪廓=輪廓[一世];

如果你想複製等高線[你]需要採取另一個矢量矢量。

-2

這是生成鏈接錯誤。看看這個:

--#ifdef _DEBUG 
--#pragma comment(lib,"opencv_core249d.lib") 
--#else 
--#pragma comment(lib,"opencv_core249.lib") <<---- your checked!! 
--#endif 

:-)