Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

FindContours hirerarcy issue

I'm trying to convert the following Matlab code into openCV. My code works really great for most of the examples I have(~700), except this one.

% Convert to BW image
 bwImg = im2bw(imageData, grayThresh);

% If we end up with totally black or white image return false status.
if all(bwImg(:)) || all(~bwImg(:))
    status = false;
    cornerXY = [];
    centroidXY = [];
    centroidMedianDistance = [];
    return;
end

  % Calculate each separated object area
cDist=regionprops(bwImg, 'Area');
cDist=[cDist.Area];

% Label each object
[bwImgLabeled, ~]=bwlabel(bwImg);

% Calculate min and max object size based on assumptions on the color
% checker size
maxLabelSize = prod(size(imageData)./[4 6]);
minLabelSize = prod(size(imageData)./[4 6]./10);

% Find label indices for objects that are too large or too small
remInd = find(cDist > maxLabelSize);
remInd = [remInd find(cDist < minLabelSize)];

% Remove over/undersized objects
for n=1:length(remInd)
    ri = bwImgLabeled == remInd(n);
    bwImgLabeled(ri) = 0;
end

% Fill any holes in the objects
bwImgLabeled = imfill(bwImgLabeled,'holes');

% Re-label the result image objects
bwImgLabeled(bwImgLabeled>0) = 1;
[bwImgLabeled, nObjs] = bwlabel(bwImgLabeled);

Here is my C++/OpenCV code

cv::Mat bwImg = Utilities::im2bw(imageData, grayThresh);    

double sum = cv::sum(bwImg)[0];
if(sum == bwImg.rows * bwImg.cols||sum == 0 )
{
    return AutomaticMacbethDetectionResults(false);
}

cv::vector<cv::vector<cv::Point> > contours_1;
cv::vector<cv::Vec4i> hierarchy_1;
cv::findContours(bwImg,contours_1,hierarchy_1,CV_RETR_TREE,   CV_CHAIN_APPROX_SIMPLE,cv::Point(0,0));*/

bwImg.convertTo(bwImg,CV_8U);
cv::vector<cv::vector<cv::Point> > contours_1;
cv::vector<cv::Vec4i> hierarchy;
cv::findContours(bwImg,contours_1,hierarchy,CV_RETR_TREE,CV_CHAIN_APPROX_NONE,cv::Point(0,0));  

double maxLabelSize = (bwImg.rows/4.0) * (bwImg.cols/6.0);
double minLabelSize = ((bwImg.rows/40.0) * (bwImg.cols/60.0));

//OPENCV hierarchy *[Next, Previous, First_Child, Parent]**
// http://docs.opencv.org/master/d9/d8b/tutorial_py_contours_hierarchy.html#gsc.tab=0

cv::vector<cv::vector<cv::Point> > goodContours;
    for (int i = 0; i < contours_1.size(); i++)
{
    double size = cv::contourArea(contours_1[i]);
    if (size < maxLabelSize && size > minLabelSize) //I added my check for hierarachy[i][2] ==-1 here! 
    {
               goodContours.push_back(contours_1[i]);
    }
}

cv::Mat filterContours = cv::Mat::zeros(bwImg.size(),CV_8UC3);  
bwImg.release();
for (int i = 0; i < goodContours.size(); i++)
{
    cv::RNG rng(12345);
    cv::Scalar color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
    cv::drawContours(filterContours,goodContours,i,color,CV_FILLED);        
}

imageData = filterContours;
filterContours.release();
/*% Re-label the result image objects
bwImgLabeled(bwImgLabeled > 0) = 1;*/
cv::threshold(imageData, imageData, 0 ,254,CV_THRESH_BINARY);

Here is the matlab output:

image description

Here is the openCV output: image description

Here is what happens when I remove CV_Fill: image description

so as far as I understand I can use the Hierarchy feature in order to understand if there is a contour which holds other contours. Hierarchy

and I added a switch to check for hierarchy[i][2] == -1 (meaning it has no children)

however this ruins my results for other images. Can you please explain the difference between regionprops and findcontours? and maybe suggests a way to solve my issue?

FindContours hirerarcy issue

I'm trying to convert the following Matlab code into openCV. My code works really great for most of the examples I have(~700), except this one.

Here is the matlab output:

image description

Here is the openCV output: image description

Here is what happens when I remove CV_Fill: image description

% Convert to BW image
 bwImg = im2bw(imageData, grayThresh);

% If we end up with totally black or white image return false status.
if all(bwImg(:)) || all(~bwImg(:))
    status = false;
    cornerXY = [];
    centroidXY = [];
    centroidMedianDistance = [];
    return;
end

  % Calculate each separated object area
cDist=regionprops(bwImg, 'Area');
cDist=[cDist.Area];

% Label each object
[bwImgLabeled, ~]=bwlabel(bwImg);

% Calculate min and max object size based on assumptions on the color
% checker size
maxLabelSize = prod(size(imageData)./[4 6]);
minLabelSize = prod(size(imageData)./[4 6]./10);

% Find label indices for objects that are too large or too small
remInd = find(cDist > maxLabelSize);
remInd = [remInd find(cDist < minLabelSize)];

% Remove over/undersized objects
for n=1:length(remInd)
    ri = bwImgLabeled == remInd(n);
    bwImgLabeled(ri) = 0;
end

% Fill any holes in the objects
bwImgLabeled = imfill(bwImgLabeled,'holes');

% Re-label the result image objects
bwImgLabeled(bwImgLabeled>0) = 1;
[bwImgLabeled, nObjs] = bwlabel(bwImgLabeled);

Here is my C++/OpenCV code

cv::Mat bwImg = Utilities::im2bw(imageData, grayThresh);    

double sum = cv::sum(bwImg)[0];
if(sum == bwImg.rows * bwImg.cols||sum == 0 )
{
    return AutomaticMacbethDetectionResults(false);
}

cv::vector<cv::vector<cv::Point> > contours_1;
cv::vector<cv::Vec4i> hierarchy_1;
cv::findContours(bwImg,contours_1,hierarchy_1,CV_RETR_TREE,   CV_CHAIN_APPROX_SIMPLE,cv::Point(0,0));*/

bwImg.convertTo(bwImg,CV_8U);
cv::vector<cv::vector<cv::Point> > contours_1;
cv::vector<cv::Vec4i> hierarchy;
cv::findContours(bwImg,contours_1,hierarchy,CV_RETR_TREE,CV_CHAIN_APPROX_NONE,cv::Point(0,0));  

double maxLabelSize = (bwImg.rows/4.0) * (bwImg.cols/6.0);
double minLabelSize = ((bwImg.rows/40.0) * (bwImg.cols/60.0));

//OPENCV hierarchy *[Next, Previous, First_Child, Parent]**
// http://docs.opencv.org/master/d9/d8b/tutorial_py_contours_hierarchy.html#gsc.tab=0

cv::vector<cv::vector<cv::Point> > goodContours;
    for (int i = 0; i < contours_1.size(); i++)
{
    double size = cv::contourArea(contours_1[i]);
    if (size < maxLabelSize && size > minLabelSize) //I added my check for hierarachy[i][2] ==-1 here! 
    {
               goodContours.push_back(contours_1[i]);
    }
}

cv::Mat filterContours = cv::Mat::zeros(bwImg.size(),CV_8UC3);  
bwImg.release();
for (int i = 0; i < goodContours.size(); i++)
{
    cv::RNG rng(12345);
    cv::Scalar color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
    cv::drawContours(filterContours,goodContours,i,color,CV_FILLED);        
}

imageData = filterContours;
filterContours.release();
/*% Re-label the result image objects
bwImgLabeled(bwImgLabeled > 0) = 1;*/
cv::threshold(imageData, imageData, 0 ,254,CV_THRESH_BINARY);

Here is the matlab output:

image description

Here is the openCV output: image description

Here is what happens when I remove CV_Fill: image description

so as far as I understand I can use the Hierarchy feature in order to understand if there is a contour which holds other contours. Hierarchy

and I added a switch to check for hierarchy[i][2] == -1 (meaning it has no children)

however this ruins my results for other images. Can you please explain the difference between regionprops and findcontours? and maybe suggests a way to solve my issue?

FindContours hirerarcy issue

I'm trying to convert the following Matlab code into openCV. My code works really great for most of the examples I have(~700), except this one.

Original Image
image description

Here is the matlab output:

image description

Here is the openCV output: image description

Here is what happens when I remove CV_Fill: image description

% Convert to BW image
 bwImg = im2bw(imageData, grayThresh);

% If we end up with totally black or white image return false status.
if all(bwImg(:)) || all(~bwImg(:))
    status = false;
    cornerXY = [];
    centroidXY = [];
    centroidMedianDistance = [];
    return;
end

  % Calculate each separated object area
cDist=regionprops(bwImg, 'Area');
cDist=[cDist.Area];

% Label each object
[bwImgLabeled, ~]=bwlabel(bwImg);

% Calculate min and max object size based on assumptions on the color
% checker size
maxLabelSize = prod(size(imageData)./[4 6]);
minLabelSize = prod(size(imageData)./[4 6]./10);

% Find label indices for objects that are too large or too small
remInd = find(cDist > maxLabelSize);
remInd = [remInd find(cDist < minLabelSize)];

% Remove over/undersized objects
for n=1:length(remInd)
    ri = bwImgLabeled == remInd(n);
    bwImgLabeled(ri) = 0;
end

% Fill any holes in the objects
bwImgLabeled = imfill(bwImgLabeled,'holes');

% Re-label the result image objects
bwImgLabeled(bwImgLabeled>0) = 1;
[bwImgLabeled, nObjs] = bwlabel(bwImgLabeled);

Here is my C++/OpenCV code

cv::Mat bwImg = Utilities::im2bw(imageData, grayThresh);    

double sum = cv::sum(bwImg)[0];
if(sum == bwImg.rows * bwImg.cols||sum == 0 )
{
    return AutomaticMacbethDetectionResults(false);
}

cv::vector<cv::vector<cv::Point> > contours_1;
cv::vector<cv::Vec4i> hierarchy_1;
cv::findContours(bwImg,contours_1,hierarchy_1,CV_RETR_TREE,   CV_CHAIN_APPROX_SIMPLE,cv::Point(0,0));*/

bwImg.convertTo(bwImg,CV_8U);
cv::vector<cv::vector<cv::Point> > contours_1;
cv::vector<cv::Vec4i> hierarchy;
cv::findContours(bwImg,contours_1,hierarchy,CV_RETR_TREE,CV_CHAIN_APPROX_NONE,cv::Point(0,0));  

double maxLabelSize = (bwImg.rows/4.0) * (bwImg.cols/6.0);
double minLabelSize = ((bwImg.rows/40.0) * (bwImg.cols/60.0));

//OPENCV hierarchy *[Next, Previous, First_Child, Parent]**
// http://docs.opencv.org/master/d9/d8b/tutorial_py_contours_hierarchy.html#gsc.tab=0

cv::vector<cv::vector<cv::Point> > goodContours;
    for (int i = 0; i < contours_1.size(); i++)
{
    double size = cv::contourArea(contours_1[i]);
    if (size < maxLabelSize && size > minLabelSize) //I added my check for hierarachy[i][2] ==-1 here! 
    {
               goodContours.push_back(contours_1[i]);
    }
}

cv::Mat filterContours = cv::Mat::zeros(bwImg.size(),CV_8UC3);  
bwImg.release();
for (int i = 0; i < goodContours.size(); i++)
{
    cv::RNG rng(12345);
    cv::Scalar color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
    cv::drawContours(filterContours,goodContours,i,color,CV_FILLED);        
}

imageData = filterContours;
filterContours.release();
/*% Re-label the result image objects
bwImgLabeled(bwImgLabeled > 0) = 1;*/
cv::threshold(imageData, imageData, 0 ,254,CV_THRESH_BINARY);

so as far as I understand I can use the Hierarchy feature in order to understand if there is a contour which holds other contours. Hierarchy

and I added a switch to check for hierarchy[i][2] == -1 (meaning it has no children)

however this ruins my results for other images. Can you please explain the difference between regionprops and findcontours? and maybe suggests a way to solve my issue?