OpenCV convexityDefects drawing

413 Views Asked by At

enter image description here

Hi. I have the above image and use the "findContours" function. And then I use the "convexity defects" functions to find the corner points.

The result is as follows.

enter image description here

The problem with this code is that it can not find the rounded corners.You can not find a point like the following.

enter image description here

This is my code

#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>
#include <iostream>
#include <sstream>
#include <fstream>

using namespace cv;
using namespace std;


int main(int argc, char** argv)
{
    cv::Mat image = cv::imread("find_Contours.png");
    //Prepare the image for findContours
    cv::cvtColor(image, image, CV_BGR2GRAY);
    cv::threshold(image, image, 128, 255, CV_THRESH_BINARY);
    //Find the contours. Use the contourOutput Mat so the original image doesn't get overwritten
    std::vector<std::vector<cv::Point> > contours;
    cv::Mat contourOutput = image.clone();
    cv::findContours(contourOutput, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
    ////convexityDefects 
    vector<vector<Point> >hull(contours.size());
    vector<vector<int> > hullsI(contours.size()); // Indices to contour points
    vector<vector<Vec4i>> defects(contours.size());
    for (int i = 0; i < contours.size(); i++)
    {
        convexHull(contours[i], hull[i], false);
        convexHull(contours[i], hullsI[i], false);
        if (hullsI[i].size() > 3) // You need more than 3 indices          
        {
            convexityDefects(contours[i], hullsI[i], defects[i]);
        }
    }
    ///// Draw convexityDefects
    for (int i = 0; i < contours.size(); ++i)
    {
        for (const Vec4i& v : defects[i])
        {
            float depth = v[3]/256;
            if (depth >= 0) //  filter defects by depth, e.g more than 10
            {
                int startidx = v[0]; Point ptStart(contours[i][startidx]);
                int endidx = v[1]; Point ptEnd(contours[i][endidx]);
                int faridx = v[2]; Point ptFar(contours[i][faridx]);
                circle(image, ptFar, 4, Scalar(255, 255, 255), 2);
                cout << ptFar << endl;

            }
        }
    }
    //
    cv::imshow("Input Image", image);
    cvMoveWindow("Input Image", 0, 0);
    //
    waitKey(0);
}

Can someone make the code and find the red dot? please help.

now i want find "convexity defects" from inside,not outside like this image: enter image description here

Someone can help me??

1

There are 1 best solutions below

0
On

It is very important to use

convexHull(contours[i], hullsI[i], true);

That is, with the last argument "true" for indices. I'm almost certain this is the reason it cannot find all the defects. Before fixing this, it is not much sense try to find other bugs (if any).