Finding contours in vector of connected points

asked 2015-04-01 12:55:19 -0500

John_E gravatar image

updated 2015-04-02 06:38:20 -0500


I use a class called ConnectedComponents to split a binary image into vectors of connected points (Point2i).

I find it convenient to use these point vectors when sorting out which blob to use. But once I sort out the appropriate object, I need to perform stuff like circularity measurements. Thus the need for contours.

Is there an algorithm for finding the contour in a vector of points?

Would it be less taxing to convert the point vector to a mat, perform canny and then findContours?


One way of doing it is:

  • Threshold image
  • Use a connectedcomponents class to store individual sets of connected pixels as points
  • Perform canny on the thresholded image
  • Find the edges
  • Map contours with the different sets of connected pixels
  • Decide what set(s) of connectedcomponents we want

What I would rather do is

  • Threshold image
  • Use a connectedcomponents class to store individual sets of connected pixels as points
  • Decide what set(s) of connected pixels to use
  • Find the edges of that single set.
edit retag flag offensive close merge delete


May be you can use this code :(class ImageInfoCV : public Mat)

if (im->statComposante==NULL)
    im->statComposante = new cv::Mat*[im1->channels()]; 
    im->centreGComposante = new cv::Mat*[im1->channels()]; 
    im->contours = new std::vector<std::vector<cv::Point> >[im1->channels()]; 
    im->arbreContour = new std::vector<cv::Vec4i> [im1->channels()]; 
    for (int i=0;i<im1->channels();i++)
        im->statComposante[i] = new cv::Mat; 
        im->centreGComposante[i] = new cv::Mat; 
connectedComponentsWithStats(*im1, *im,*(im->statComposante[0]),*(im->centreGComposante[0]), paramOCV->intParam["connectivity"].valeur, CV_32S);
ImageInfoCV imCtr ;
findContours(imCtr, *(im->contours),*im->arbreContour, cv::RETR_CCOMP, cv::CHAIN_APPROX_NONE, cv::Point(0,0));
LBerger gravatar imageLBerger ( 2015-04-01 13:00:53 -0500 )edit

I don't understand your question. The cv.:findContours function will already split a binary image into a vector of a vector of contour points (X-, Y- coordinates).

You have to differ between a data set of gray values (or binary values) and a set of X-, Y- coordiantes. The first one you get when you threshold an image e.g. with cv::Canny or cv::threshold. The second one you get with cv::findContour, which is applied after thresholding. There is also a function cv::connectedComponents which will split your image into a new image (with gray values) where every connected area will get an increasing value starting by 1.

So when you want to do blob analysis I recommend you to do a threshold and then findContour, after that you can calculate moments with cv::moments for example.

matman gravatar imagematman ( 2015-04-01 13:19:17 -0500 )edit

@matman ConnectedComponents stores the points of all connected pixels in a cluster, which is useful for other stuff I'm doing. I thought it would be nice to be able to find which of those points describes the contour of the blob without having to threshold again in the canny algorithm.

John_E gravatar imageJohn_E ( 2015-04-01 13:33:18 -0500 )edit

@LBerger It looks like there is a couple of lines missing in your code window. Could you edit your comment please?

John_E gravatar imageJohn_E ( 2015-04-01 13:51:51 -0500 )edit

I have change the code :

Mat imSrc;// It's a binary image your data
Mat imDst;// label image result
statComposante = new cv::Mat; 
centreGComposante = new cv::Mat; 
contours = new std::vector<std::vector<cv::Point> >; 
arbreContour = new std::vector<cv::Vec4i> ; 
connectedComponentsWithStats(imSrc, imDst,statComposante,centreGComposante, 8, CV_32S);
Mat imCtr ; 
imSrc.copyTo(imCtr);// find contours modify data 
findContours(imCtr, contours,arbreContour, cv::RETR_CCOMP, cv::CHAIN_APPROX_NONE, cv::Point(0,0));

You can use contour to plot all contour of your label image : contour[i] is contour of region with label i and all points are contour[i][0]...contour[i][contour[i].size()-1] You can use example opencv\samples\cpp\contours2.cpp

LBerger gravatar imageLBerger ( 2015-04-01 14:10:37 -0500 )edit

@LBerger I am currently using opencv-2.4.9 with a custom ConnectedComponents class. Your solution looks like it is using opencv-3. Is that correct?

John_E gravatar imageJohn_E ( 2015-04-01 15:47:31 -0500 )edit

Sorry I forget it I use OpenCV 3.0 dev

LBerger gravatar imageLBerger ( 2015-04-02 00:28:10 -0500 )edit

@LBerger I just compiled opencv-3. My application should be simple enough to be able to use opencv-3 without any hidden bugs...

John_E gravatar imageJohn_E ( 2015-04-02 05:10:07 -0500 )edit