Ask Your Question
1

How to use approxPolyDP to close contours

asked 2015-10-30 20:52:07 -0600

vitruvius gravatar image

updated 2015-10-30 20:55:51 -0600

Hi,

I would like to use approxPoly to close contours. But I am not quite sure about how it works.

I am using OpenCV 2.4.11.

So I have two images:

image description

image description

And I apply canny, then find contours.

image description

image description

How can I close those contour curves?

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>

using namespace cv;
RNG rng(12345);

int main()
{
    Mat src, srcGray, srcBlur, srcThresh, srcCanny;

    src = imread("source.png", 1);
    cvtColor(src, srcGray, CV_BGR2GRAY);
    blur(srcGray, srcBlur, Size(3, 3));

    double otsu;    
    otsu = threshold(srcBlur, srcThresh, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);    
    Canny(srcBlur, srcCanny, otsu, otsu * 2, 3, true);

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    findContours(srcCanny, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
    Mat drawing = Mat::zeros(srcCanny.size(), CV_8UC3);
    for (int i = 0; i< contours.size(); i++)
    {
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
    }

    imshow("Contours", drawing);

    cvWaitKey();
    return 0;
}

I tried something like this but it made it didn't help at all.

vector<vector<Point> > approx;

    approx.resize(contours.size());
    for (intk = 0; k < contours.size(); k++)
        approxPolyDP(Mat(contours[k]), approx[k], 3, true);
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
3

answered 2015-10-31 14:11:36 -0600

updated 2015-11-07 15:49:03 -0600

first of all i think there must be a better way to get external contours of an object when the background is like your images ( this is another question).

as an answer for your question i suggest to use convexHull

a sample usage based on your code is below.

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>

using namespace cv;
using namespace std;

vector<Point> contoursConvexHull( vector<vector<Point> > contours )
{
    vector<Point> result;
    vector<Point> pts;
    for ( size_t i = 0; i< contours.size(); i++)
        for ( size_t j = 0; j< contours[i].size(); j++)
            pts.push_back(contours[i][j]);
    convexHull( pts, result );
    return result;
}

int main( int, char** argv )
{
    Mat src, srcGray,srcBlur,srcCanny;

    src = imread( argv[1], 1 );
    cvtColor(src, srcGray, CV_BGR2GRAY);
    blur(srcGray, srcBlur, Size(3, 3));

    Canny(srcBlur, srcCanny, 0, 100, 3, true);

    vector<vector<Point> > contours;

    findContours( srcCanny, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE );

    Mat drawing = Mat::zeros(srcCanny.size(), CV_8UC3);

    for (int i = 0; i< contours.size(); i++)
    {
        Scalar color = Scalar( 255,255,255);
        drawContours( drawing, contours, i, color, 2 );
    }

    vector<Point> ConvexHullPoints =  contoursConvexHull(contours);

    polylines( drawing, ConvexHullPoints, true, Scalar(0,0,255), 2 );
    imshow("Contours", drawing);

    polylines( src, ConvexHullPoints, true, Scalar(0,0,255), 2 );
    imshow("contoursConvexHull", src);
    waitKey();
    return 0;
}

result images :

image description image description image description

edit flag offensive delete link more

Comments

This is great. What would you suggest if there is more than one object in the image? Like if those two were in the same image, convexHull wouldn't work.

vitruvius gravatar imagevitruvius ( 2015-10-31 16:22:25 -0600 )edit

@sturkmen With hypothesis one object by image you can use threshold

LBerger gravatar imageLBerger ( 2015-11-01 03:23:27 -0600 )edit

maybe this helps about images having more than one object. also take a look here

sturkmen gravatar imagesturkmen ( 2015-11-02 07:26:53 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-10-30 20:52:07 -0600

Seen: 44,660 times

Last updated: Nov 07 '15