openCv contour holes not working? 0072

Am I right in saying a hole=true is where a blob exists within another blob?

The openCV example looks like this:

  
  
contourFinder.findContours(grayDiff, 20, (340*240)/3, 10, true);	// find holes  
  

and if you run it with the hand video and this code added:

  
  
if(contourFinder.blobs.size()>0){  
    printf("hole=%i\n", (int)contourFinder.blobs[0].hole);  
}  
  

It comes up as hole=1

in ofxCvContourFinder this
float area = cvContourArea( cvSeqBlobs[i], CV_WHOLE_SEQ, true ); // oriented=true for holes
is producing a negative number on that hand video blob

therefore setting this to true
blobs[i].hole = area < 0 ? true : false;

i’m looking to get interior blobs like inside arm joins etc

(img via http://flong.com/projects/ifp/)

thanks

In contour finder it has:

  
  
	CvContourRetrievalMode  retrieve_mode  
        = (bFindHoles) ? CV_RETR_LIST : CV_RETR_EXTERNAL;  
  

options are:

  
  
enum  
{  
    RETR_EXTERNAL=CV_RETR_EXTERNAL, //!< retrieve only the most external (top-level) contours  
    RETR_LIST=CV_RETR_LIST, //!< retrieve all the contours without any hierarchical information  
    RETR_CCOMP=CV_RETR_CCOMP, //!< retrieve the connected components (that can possibly be nested)  
    RETR_TREE=CV_RETR_TREE //!< retrieve all the contours and the whole hierarchy  
};  
  

So CV_RETR_LIST returns everything, but then uses

  
  
float area = cvContourArea( cvSeqBlobs[i], CV_WHOLE_SEQ, true ); // oriented=true for holes  
blobs[i].hole                     = area < 0 ? true : false;  
  

to work out if its a hole.

that function looks like:

  
  
/* Calculates area of a contour or contour segment */  
CVAPI(double)  cvContourArea( const CvArr* contour,  
                              CvSlice slice CV_DEFAULT(CV_WHOLE_SEQ),  
                              int oriented CV_DEFAULT(0));  
  

http://docs.opencv.org/modules/imgproc/doc/structural-analysis-and-shape-descriptors.html?#contourarea

oriented – Oriented area flag. If it is true, the function returns a signed area value, depending on the contour orientation (clockwise or counter-clockwise). Using this feature you can determine orientation of a contour by taking the sign of an area. By default, the parameter is false, which means that the absolute value is returned.

I’m none the wiser :frowning:

Dan Wilcox says via email…

From my notes form 2 years ago:

Here is the commit where they changed it in OpenCV: https://code.ros.org/trac/opencv/changeset/2927 Note that it now sets oriented to false by default. That gives no negative blobs as you can see they are running fabs when its false in the last lines of the diff. That’s why I removed the extra fabs that were being called in OF since it’s now called within CV if you don;t want negative blobs.

Also, here’s someone complaining about that parameter: https://code.ros.org/trac/opencv/ticket/123

Again, this could have been changed in the meantime and I would check this against the latest CV’s api.

off to investigate…

So it seems it was fixed here
https://github.com/openframeworks/openFrameworks/commit/2b6f6f59afc31aec6eba0f73e24558d620be9af6

Looking through my folders, that was live in the 0071 update.

If version.hpp inside 0071/addon/opencv is right, it is

#define CV_MAJOR_VERSION 2
#define CV_MINOR_VERSION 3
#define CV_SUBMINOR_VERSION 1

Looking at the same file in 0072 openCV version hasn’t changed, so I’m confused as to why the hole stuff doesn’t work.

Could someone else using 0072 please edit the opencv example and after this line:

contourFinder.findContours(grayDiff, 20, (340*240)/3, 10, true);

add…

if(contourFinder.blobs.size()>0){
printf(“hole=%i\n”, (int)contourFinder.blobs[0].hole);
}

tell me what it says, if it thinks the hand blob is a hole or not.

Thanks!

Dan has fixed this now & will do a pull request on github. Thanks Dan!