Finding contours in vector of connected points [closed]

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

John_E gravatar image

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

Hi!

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?

EDIT

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 reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by sturkmen
close date 2020-09-28 06:34:23.869906

Comments

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 ;
im->copyTo(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 -0600 )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 -0600 )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 -0600 )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 -0600 )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 -0600 )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 -0600 )edit

Sorry I forget it I use OpenCV 3.0 dev

LBerger gravatar imageLBerger ( 2015-04-02 00:28:10 -0600 )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 -0600 )edit