Finding the convex hull of an object in opencv?

2020-06-27 09:03发布

问题:

I've written this based on the tutorial here but I'm unable to obtain the convex hull of the image (I'm using a similar hand image as shown in the tutorial). I get the source and edges output fine but the "Drawings" output which should draw the contour and convex hull lines don't show anything drawn and instead is completely black. Any ideas as to why this could be?

#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv/cxcore.h>

int main(int argc,char **argv)
{
    cvNamedWindow( "Source", 1 );
    cvNamedWindow( "edges window", 1 );
    cvNamedWindow( "Drawings", 1 );

    IplImage* src = cvLoadImage( "img.jpg", 0 );
    IplImage* edges = cvCreateImage( cvGetSize(src), 8, 1 );

    // Finding edges
    cvThreshold( src, edges, 150, 255, CV_THRESH_BINARY );

    CvMemStorage* storage = cvCreateMemStorage();
    CvSeq* first_contour = NULL;

    int Nc = cvFindContours(
        edges,
        storage,
        &first_contour,
        sizeof(CvContour),
        CV_RETR_LIST );

    // Finding convex Hull
    CvMemStorage* hull_storage = cvCreateMemStorage();
    CvSeq* retHulls = NULL;

    for(CvSeq* i = first_contour; i != 0; i = i->h_next){
    // note h_next is next sequence.
    retHulls = cvConvexHull2(first_contour,hull_storage,CV_CLOCKWISE,1);

    }

    // drawing contours and hull
    IplImage* draw = cvCreateImage(cvGetSize(edges), 8, 3 );

    for(CvSeq* i = first_contour; i != 0; i = i->h_next){
        cvDrawContours(draw,first_contour,cvScalar(255,0,0,0),cvScalar(255,0,0,0),0,1,8);
        cvDrawContours(draw,retHulls,cvScalar(255,0,0,0),cvScalar(255,0,0,0),0,1,8);

    }

    cvShowImage( "Source", src );
    cvShowImage( "edges window", edges );
    cvShowImage( "Drawings", draw );
    cvWaitKey();

    cvDestroyAllWindows();

    cvReleaseImage( &src );
    cvReleaseImage( &edges );
    cvReleaseImage( &draw );

    return 0;
}

回答1:

You have to do the following changes:

  1. Change parameter from CV_RETR_LIST to CV_RETR_EXTERNAL in cvFindContours function.
  2. Change CV_THRESH_BINARY to CV_THRESH_OTSU in cvThreshold.

Here's proof (input/output):



回答2:

there is 2 methods,

  1. opencv convex hull

http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/hull/hull.html

http://code.opencv.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp

  1. cvblob convex hull

https://code.google.com/p/cvblob/

https://code.google.com/p/cvblob/source/browse/trunk/cvBlob/cvblob.h?r=398

CvContourPolygon *cvPolygonContourConvexHull(CvContourPolygon const *p);

HTH