简体   繁体   English

openCV和cvBlobs与matlab给出的结果不同

[英]openCV and cvBlobs not giving same results as matlab

here is my matlab code: 这是我的matlab代码:

 % 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 
    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);

the number of object which is found here is 18; 在这里找到的对象数为18;

here is my openCV and cvBlobs code 这是我的openCV和cvBlobs代码

//regionprops(bwImg, 'Area');
// cDist=[cDist.Area]
dst.convertTo(dst,CV_8U);
cv::vector<cv::vector<cv::Point> > contours_1;
cv::vector<cv::Vec4i> hierarchy_1;
cv::findContours(dst,contours_1,hierarchy_1,CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);

//DEBUG contours
cv::Mat drawing1 = cv::Mat::zeros(dst.size(),CV_8UC3);  
for (int i = 0; i < contours_1.size(); i++)
{
    cv::RNG rng(12345);
    cv::Scalar color = cv::Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
    drawContours( drawing1, contours_1, i, color, 2, 8, hierarchy_1, 0, cv::Point() );
}

std::vector<cv::Moments> mu(contours_1.size());
for (int i = 0; i < contours_1.size(); i++)
{
    mu[i] = cv::moments(contours_1[i],false);
}
vector<cv::Point2f> mc( contours_1.size() );
for( int i = 0; i < contours_1.size(); i++ )
{ 
    mc[i] = cv::Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); 
}

/// Draw contours
cv::Mat drawing = cv::Mat::zeros(dst.size(),CV_8UC3);   
for (int i = 0; i < contours_1.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( drawing, contours_1, i, color, 2, 8, hierarchy_1, 0, cv::Point() );
    cv::circle( drawing, mc[i], 4, color, -1, 8, 0 );
}

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

//% 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

IplImage* img_bw_1 = new IplImage(dst);
CBlobResult blobs_1;
CBlob *currentBlob;
blobs_1 = CBlobResult(img_bw_1, NULL, 0);

blobs_1.Filter( blobs_1, B_EXCLUDE, CBlobGetArea(), B_LESS, minLabelSize);
blobs_1.Filter(blobs_1,B_EXCLUDE,CBlobGetArea(),B_GREATER,maxLabelSize);
// Get the number of blobs discovered
int num_blobs = blobs_1.GetNumBlobs(); 

// Display the filtered blobs
IplImage* filtered = cvCreateImage( cvGetSize( img_bw_1 ),
    IPL_DEPTH_8U,
    3 );    

for ( int i = 0; i < num_blobs; i++ )
{
    currentBlob = blobs_1.GetBlob( i );
    currentBlob->FillBlob( filtered, CV_RGB(30+i*10,30+i*10,30+i*10));
}

img_bw_1 = NULL;
delete img_bw_1;
currentBlob= NULL;
delete currentBlob;


/*% Fill any holes in the objects
bwImgLabeled = imfill(bwImgLabeled,'holes');*/
dst = filtered;
cv::floodFill(dst, cv::Point(1,1), CV_RGB(0,0,0));     

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

cv::threshold(dst, dst, 0 ,30,CV_THRESH_BINARY);

the result here is 17 objects. 这里的结果是17个对象。

Can you please check what I have done wrong?is it something which has to do with precision? 您能检查一下我做错了吗?这与精度有关吗? float in openCV vs. double in matlab? 浮动在OpenCV与在Matlab中的两倍? is it because of the different implementation of matlab and openCV? 是因为matlab和openCV的实现方式不同?

I suspect these lines: 我怀疑这些行:

blobs_1.Filter( blobs_1, B_EXCLUDE, CBlobGetArea(), B_LESS, minLabelSize);
blobs_1.Filter(blobs_1,B_EXCLUDE,CBlobGetArea(),B_GREATER,maxLabelSize);

because the number of element from this blobs_1 = CBlobResult(img_bw_1, NULL, 0); 因为来自此blobs_1 = CBlobResult(img_bw_1, NULL, 0);的元素数blobs_1 = CBlobResult(img_bw_1, NULL, 0); is 271 and the areas of the blobs which are found in cvblobslib is different from what is found in matlab's regionprops - which returns 261 blobs with different area sizes 是271,在cvblobslib中找到的斑点的面积与在matlab的regionprops中发现的斑点不同-后者返回261个具有不同面积大小的斑点

this is my final working solution hope it helps someone it the future. 这是我最终的工作解决方案,希望对以后的人有所帮助。 I'm using openCV 2.4.10. 我正在使用openCV 2.4.10。 there is no need to use cvBlobs. 无需使用cvBlob。 openCV findContours and drawContours can do almost anything it does. openCV findContours和drawContours几乎可以做任何事情。 just have to play with the right flags of the functions. 只需使用正确的功能标记即可。

    bwImg.convertTo(bwImg,CV_8U);
    cv::vector<cv::vector<cv::Point> > contours_1;
    cv::findContours(bwImg,contours_1,CV_RETR_TREE,CV_CHAIN_APPROX_NONE,cv::Point(0,0));
    //DEBUG contours
    cv::Mat drawing1 = cv::Mat::zeros(bwImg.size(),CV_8UC3);    

    for (int i = 0; i < contours_1.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(drawing1,contours_1,i,color,CV_FILLED);
    }   
    //% 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);
    double maxLabelSize = (bwImg.rows/4.0) * (bwImg.cols/6.0);
    double minLabelSize = ((bwImg.rows/40.0) * (bwImg.cols/60.0));


    //  % Remove over/undersized objects
    //  for n=1:length(remInd)
    //      ri = bwImgLabeled == remInd(n);
    //      bwImgLabeled(ri) = 0;
    //  end
    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)
        {
            goodContours.push_back(contours_1[i]);
        }
    }

    cv::Mat filterContours = cv::Mat::zeros(bwImg.size(),CV_8UC3);  
    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);        
    }

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


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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM