2015-03-26 3 views
2

вот мой код MATLAB:OpenCV и cvBlobs не дает те же результаты, как 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); 

количество объекта, который находится здесь 18;

вот мой 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); 

результат здесь 17 объектов.

Не могли бы вы проверить, что я сделал неправильно? Это что-то, что связано с точностью? плавать в openCV против double в matlab? это из-за различной реализации matlab и openCV?

Я подозреваю, что эти строки:

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

, так как число элементов из этого blobs_1 = CBlobResult(img_bw_1, NULL, 0); является 271 и площадь блобова, которые находятся в cvblobslib отличается от того, что находится в regionprops MatLab - который возвращает 261 капли с разными размерами площадей

ответ

0

Это мое окончательное рабочее решение, надеясь, что это поможет кому-то в будущем. Я использую openCV 2.4.10. нет необходимости использовать cvBlobs. openCV findContours и drawContours могут делать почти все, что он делает. просто должны играть с правильными флагами функций.

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); 
Смежные вопросы