Ask Your Question

Revision history [back]

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> allcontours;
    for ( size_t i = 0; i< contours.size(); i++)
        for ( size_t j = 0; j< contours[i].size(); j++)
            allcontours.push_back(contours[i][j]);
    convexHull( allcontours, 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

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> allcontours;
    for ( size_t i = 0; i< contours.size(); i++)
        for ( size_t j = 0; j< contours[i].size(); j++)
            allcontours.push_back(contours[i][j]);
    convexHull( allcontours, 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

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> allcontours;
pts;
    for ( size_t i = 0; i< contours.size(); i++)
        for ( size_t j = 0; j< contours[i].size(); j++)
            allcontours.push_back(contours[i][j]);
pts.push_back(contours[i][j]);
    convexHull( allcontours, 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