首页 文章

OpenCV最后的凸性缺陷不对

提问于
浏览
0

我正在尝试编写代码来跟踪手 . 我使用凸性缺陷函数来找到手指,但由于某种原因,最后一个缺陷似乎总是存在问题 .

Here is a picture of what I'm talking about(抱歉,我是论坛的新手,所以无法发布图片)

青色线是轮廓,黄线是船体点,红线是缺陷点 . 如您所见,最后一个缺陷点从轮廓的错误一侧检测到缺陷 .

这是我的代码:

#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中的错误还是我做错了什么?

2 回答

  • 1

    我用下面的图像测试了你的代码(稍作修改)(OpenCV版本是3.2) .

    正如您在结果图像上看到的那样,它按预期工作 . 可能你正在使用旧版本的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

    我有一个解决方案,涉及使用OpenCV检测皮肤 . 我使用 python 实现了它,您可以轻松地将其转换为C.

    我使用以下方法获取了您上传的图像的HSV值:

    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)
    

    然后我执行 morphological dilation 并获得以下内容:

    enter image description here

    您现在可以应用轮廓外壳并找到凸起缺陷 .

相关问题