2017-02-01 9 views
0

私は手を追跡するコードを書こうとしています。私は指を見つけるために凸欠陥機能を使用していますが、何らかの理由で、常に最後の欠陥に問題があるようです。OpenCV最後の凸凹が正しくない

Here is a picture of what I'm talking about(申し訳ありませんが、i''mがフォーラムに新しいので、画像を投稿することはできません)

シアンラインが黄色の線が船体ポイントで、赤線が欠陥ポイントである、輪郭です。あなたが見ることができるように、最後の欠陥点は、輪郭の間違った側から欠陥を検出する。ここで

は私のコードです:

#include "opencv2\opencv.hpp" 

using namespace cv; 
using namespace std; 

int main() { 
    VideoCapture cap(0); 
    Mat src, gray, background, binary, diff; 
    cap >> background; 
    cvtColor(background, background, CV_BGR2GRAY); 
    vector<vector<Point>> contours; 
    vector < vector<int>> hullI = vector<vector<int>>(1); 
    vector < vector<Point>> hullP = vector<vector<Point>>(1); 
    vector<Vec4i> defects; 
    while (waitKey(30)!='q') { 
     cap >> src; 
     cvtColor(src, gray, CV_BGR2GRAY); 
     blur(gray, gray, Size(3, 3)); 
     absdiff(gray, background, diff); 
     threshold(diff, binary, 15, 255, THRESH_BINARY); 
     erode(binary, binary, Mat(Size(5, 5), CV_8U)); 

     imshow("binary", binary); 

     findContours(binary, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); 
     if (!contours.empty()) { 
      sort(contours.begin(), contours.end(), [](vector<Point> a, vector<Point> b) { return a.size() > b.size(); }); 
      drawContours(src, contours, 0, Scalar(255, 255, 0)); 

      convexHull(contours[0], hullI[0]); 
      convexHull(contours[0], hullP[0]); 
      drawContours(src, hullP, 0, Scalar(0, 255, 255)); 

      if (hullI[0].size() > 2) { 
       convexityDefects(contours[0], hullI[0], defects); 

       for (Vec4i defect : defects) { 
        line(src, contours[0][defect[0]], contours[0][defect[2]], Scalar(0, 0, 255)); 
        line(src, contours[0][defect[1]], contours[0][defect[2]], Scalar(0, 0, 255)); 
       } 
      } 
     } 
     imshow("src", src); 
     char key = waitKey(30); 
     if (key == 'q')break; 
     else if (key == 'p') waitKey(); 
     else if (key == 'b') { 
      cap >> background; 
      cvtColor(background, background, CV_BGR2GRAY); 
     } 
    } 
} 

私はそれは常に、これはあまりにも起こる欠陥ベクトルの最後の欠陥であることを実験により確認しています。これはopencvのバグですか、何か間違っていますか?

答えて

1

以下の画像(OpenCVバージョンは3.2)を使用してコードを修正しました。

結果画像に表示されているように、期待どおりに動作します。おそらくあなたは古いバージョンのOpenCVを使っていて、バグのある結果を得ているでしょう。私はOpenCVのを使用して皮膚を検出することを伴う解決策を持っている

enter image description here

enter image description here

#include "opencv2\opencv.hpp" 

using namespace cv; 
using namespace std; 

int main() { 
    //VideoCapture cap(0); 
    Mat src, gray, background, binary, diff; 
    //cap >> background; 
    //cvtColor(background, background, CV_BGR2GRAY); 
    vector<vector<Point> > contours; 
    vector < vector<int> > hullI = vector<vector<int> >(1); 
    vector < vector<Point> > hullP = vector<vector<Point> >(1); 
    vector<Vec4i> defects; 
     src = imread("hand.png"); 
     cvtColor(src, gray, CV_BGR2GRAY); 
     blur(gray, gray, Size(3, 3)); 
     threshold(gray, binary, 150, 255, THRESH_BINARY_INV); 
     //erode(binary, binary, Mat(Size(5, 5), CV_8U)); 
     imshow("binary", binary); 
     findContours(binary, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); 
     if (!contours.empty()) { 
      sort(contours.begin(), contours.end(), [](vector<Point> a, vector<Point> b) { return a.size() > b.size(); }); 
      drawContours(src, contours, 0, Scalar(255, 255, 0)); 

      convexHull(contours[0], hullI[0]); 
      convexHull(contours[0], hullP[0]); 
      drawContours(src, hullP, 0, Scalar(0, 255, 255)); 

      if (hullI[0].size() > 2) { 
       convexityDefects(contours[0], hullI[0], defects); 

       for (Vec4i defect : defects) { 
        line(src, contours[0][defect[0]], contours[0][defect[2]], Scalar(0, 0, 255)); 
        line(src, contours[0][defect[1]], contours[0][defect[2]], Scalar(0, 0, 255)); 
       } 
      } 
     } 
     imshow("result", src); 
     char key = waitKey(0); 
     return 0; 
    } 
+0

こんにちは@Matthew私の答えを受け入れることに感謝します。古いバージョンのOpenCVを使用しましたか? – sturkmen

0

(私はそれが最近、固定バグだったと思います)。私はpythonを使って実装しました。これは簡単にC++に変換できます。

hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 

これは、人間の皮膚のHSV値の範囲は:私は、形態学的拡張を行い、得られ

l = np.array([0, 48, 80], dtype = "uint8") 
u = np.array([20, 255, 255], dtype = "uint8") 

skin_img = cv2.inRange(hsv_img, l, u) 
cv2.imshow("Hand", skin_img) 

は、私が使用してアップロードした画像のHSV値を得ました以下:

enter image description here

輪郭線を適用して凸欠陥を見つけることができるようになりました。

関連する問題