1

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??

Community
  • 1
  • 1
kasra
  • 55
  • 7
  • `convexityDefects` doesn't find the corners, it finds the farthest point from the convex hull for each convexity (== region where the contour departs from the convex hull). It won't find the corners that "stick out" and therefore are part of the convex hull. – Cris Luengo Jul 10 '18 at 17:30

1 Answers1

1

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).

Cynichniy Bandera
  • 5,991
  • 2
  • 29
  • 33