【问题标题】:Find point of convexity defects in opencv c++ function在opencv c ++函数中找到凸缺陷点
【发布时间】:2013-08-24 00:11:45
【问题描述】:

我正在尝试恢复凸性缺陷点,但该函数只返回整数,你能告诉我如何找到这些点吗?

    vector<vector<Point> >hull2( contours.size() );
          vector<vector<int>> hull(contours.size());
std::vector<cv::Vec4i> convexityDefectsSet;    

   for( int i = 0; i < contours.size(); i++ )   {
      convexHull( Mat(contours[i]), hull[i], false );
        convexHull(Mat(contours[i]), hull2[i], false);
      if (contours[i].size() > 3) {
      cv::convexityDefects(Mat(contours[i]), hull[i], convexityDefectsSet);

      for (int cDefIt = 0; cDefIt < convexityDefectsSet.size(); cDefIt++) {

            int startIdx = convexityDefectsSet[cDefIt].val[0];

            int endIdx = convexityDefectsSet[cDefIt].val[1];

            int defectPtIdx = convexityDefectsSet[cDefIt].val[2];

            double depth = static_cast<double>(convexityDefectsSet[cDefIt].val[3]) / 256.0;

            std::cout << startIdx << ' ' << endIdx << ' ' << defectPtIdx << ' ' << depth << '\n' << '\n' << std::endl;

            Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
            Point2f p(defectPtIdx, defectPtIdx);
            circle(frame, p , 10, color, 2, 8, 0 );
        }
      }}

【问题讨论】:

    标签: c++ opencv


    【解决方案1】:

    我认为这是我的一段代码(应该检测手(需要调整颜色检测器)并搜索转换缺陷)。但是您可以将其用作代码的基础:

    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    #include <ctype.h>
    #include <time.h> 
    
    #include <opencv2\imgproc\imgproc.hpp>
    #include <opencv2\video\tracking.hpp>
    #include <opencv2\highgui\highgui.hpp>
    
    using namespace cv;
    using namespace std;
    
    // Detect Skin from YCrCb
    Mat DetectYCrCb(Mat img, Scalar min, Scalar max) {
        Mat skin;
        cvtColor(img, skin, cv::COLOR_BGR2YCrCb);
        inRange(skin, min, max, skin);
        Mat rect_12 = getStructuringElement(cv::MORPH_RECT, Size(12,12) , Point(6,6));
        erode(skin, skin, rect_12,Point(),1);
        Mat rect_6 = getStructuringElement(cv::MORPH_RECT, Size(6,6) , Point(3,3));
        dilate(skin,skin,rect_6,Point(),2);
        return skin;    
    }
    
    void DetectContour(Mat img){
        Mat drawing = Mat::zeros( img.size(), CV_8UC3 );
        vector<vector<Point> > contours;
        vector<vector<Point> > bigContours;
        vector<Vec4i> hierarchy;
    
        findContours(img,contours, hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE, Point());
    
        if(contours.size()>0)
        {
            vector<std::vector<int> >hull( contours.size() );
            vector<vector<Vec4i>> convDef(contours.size() );
            vector<vector<Point>> hull_points(contours.size());
            vector<vector<Point>> defect_points(contours.size());
    
    
            for( int i = 0; i < contours.size(); i++ )
            {
                if(contourArea(contours[i])>5000)
                {
                    convexHull( contours[i], hull[i], false );
                    convexityDefects( contours[i],hull[i], convDef[i]);
    
                    for(int k=0;k<hull[i].size();k++)
                    {           
                        int ind=hull[i][k];
                        hull_points[i].push_back(contours[i][ind]);
                    }
    
                    for(int k=0;k<convDef[i].size();k++)
                    {           
                        if(convDef[i][k][3]>20*256) // filter defects by depth
                        {
                        int ind_0=convDef[i][k][0];
                        int ind_1=convDef[i][k][1];
                        int ind_2=convDef[i][k][2];
                        defect_points[i].push_back(contours[i][ind_2]);
                        cv::circle(drawing,contours[i][ind_0],5,Scalar(0,255,0),-1);
                        cv::circle(drawing,contours[i][ind_1],5,Scalar(0,255,0),-1);
                        cv::circle(drawing,contours[i][ind_2],5,Scalar(0,0,255),-1);
                        cv::line(drawing,contours[i][ind_2],contours[i][ind_0],Scalar(0,0,255),1);
                        cv::line(drawing,contours[i][ind_2],contours[i][ind_1],Scalar(0,0,255),1);
                        }
                    }
    
                    drawContours( drawing, contours, i, Scalar(0,255,0), 1, 8, vector<Vec4i>(), 0, Point() );
                    drawContours( drawing, hull_points, i, Scalar(255,0,0), 1, 8, vector<Vec4i>(), 0, Point() );
                }
            }
        }
        imshow( "Hull demo", drawing );
    }
    
    
    int main( int argc, char** argv )
    {
        Mat frame,copyFrame;
        VideoCapture capture(0);
        namedWindow( "Hull demo", cv::WINDOW_AUTOSIZE );
        namedWindow( "Video", cv::WINDOW_AUTOSIZE );
        if (capture.isOpened()){
            while(true)
            {
                capture >> frame;
                imshow( "Video", frame);
    
                Mat skinYCrCb = DetectYCrCb(frame,Scalar(0, 100, 80), Scalar(255, 185, 135));
    
                DetectContour(skinYCrCb);
    
                int c = waitKey(10);
                if( (char)c == 27 ) 
                { 
                    break; 
                } 
            }
        }
        cv::destroyAllWindows();
        return 0;
    }
    

    【讨论】:

    • 非常感谢!我有一个上大学的项目,需要学习如何找到这些点来完成
    【解决方案2】:

    根据documentation

    In C++ and the new Python/Java interface each convexity defect is represented 
    as 4-element integer vector [...]: (start_index, end_index, farthest_pt_index, 
    fixpt_depth), where indices are 0-based indices in the original contour of 
    the convexity defect...
    

    它们对应于用于生成凸包的原始轮廓中的索引,即您的 contours[i] 变量。 例如,第一个点的坐标通过以下方式获得:

    cv::Point start = contours.at(startIdx);
    

    【讨论】:

    • 我已经扩展了答案。
    猜你喜欢
    • 2011-10-12
    • 2013-02-20
    • 2012-10-10
    • 2013-09-03
    • 2012-01-05
    • 2012-02-27
    • 1970-01-01
    • 2012-06-13
    • 2015-09-29
    相关资源
    最近更新 更多