OpenCV - найти ограничивающий прямоугольник с наибольшим блобом в бинарном изображении

Каков наиболее эффективный способ найти ограничительную рамку самого большого блоба в двоичном изображении с помощью OpenCV? К сожалению, OpenCV не имеет специфических функций для обнаружения blob. Должен ли я просто использовать findContours() и искать самое большое в списке?

Ответ 1

Если вы хотите использовать библиотеки OpenCV, проверьте OpenCVs SimpleBlobDetector. Здесь еще один переполнение стека показывает небольшой учебник по нему: Как использовать OpenCV SimpleBlobDetector

Это только дает вам ключевые моменты. Вы можете использовать это как начальный поиск, чтобы найти желаемый blob, а затем, возможно, использовать алгоритм findContours вокруг наиболее вероятных блоков.

Кроме того, чем больше информации вы знаете о своем блобе, вы можете предоставить параметры для фильтрации нежелательных блоков. Вы можете проверить параметры области SimpleBlobDetector. Возможно, он мог бы вычислить область в зависимости от размера области изображения, а затем итеративно разрешить меньшую blob, если алгоритм не обнаруживает никаких капель.

Вот ссылка на основную документацию OpenCV: http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html#simpleblobdetector

Ответ 2

Здесь. Это. Является. (FYI: постарайтесь не лениться и выяснить, что происходит в моей функции ниже.

cv::Mat findBiggestBlob(cv::Mat & matImage){
    int largest_area=0;
    int largest_contour_index=0;

    vector< vector<Point> > contours; // Vector for storing contour
    vector<Vec4i> hierarchy;

    findContours( matImage, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image

    for( int i = 0; i< contours.size(); i++ ) {// iterate through each contour. 
        double a=contourArea( contours[i],false);  //  Find the area of contour
        if(a>largest_area){
            largest_area=a;
            largest_contour_index=i;                //Store the index of largest contour
            //bounding_rect=boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
        }
    }

    drawContours( matImage, contours, largest_contour_index, Scalar(255), CV_FILLED, 8, hierarchy ); // Draw the largest contour using previously stored index.
    return matImage;
}

Ответ 3

Чтобы найти ограничивающий прямоугольник самого большого блоба, я использовал findContours, а затем следующий код:

double maxArea = 0;
for (MatOfPoint contour : contours) {
    double area = Imgproc.contourArea(contour);
    if (area > maxArea) {
        maxArea = area;
        largestContour = contour;
    }
}
Rect boundingRect = Imgproc.boundingRect(largestContour);

Ответ 5

TimZaman, ваш код имеет ошибку, но я не могу комментировать, поэтому я начинаю новый и правильный ответ. Вот мое решение, основанное на идеях 1 и Тимзамана:

Mat measure::findBiggestBlob(cv::Mat &src){
int largest_area=0;
int largest_contour_index=0;
Mat temp(src.rows,src.cols,CV_8UC1);
Mat dst(src.rows,src.cols,CV_8UC1,Scalar::all(0));
src.copyTo(temp);

vector<vector<Point>> contours; // storing contour
vector<Vec4i> hierarchy;

findContours( temp, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );

for( int i = 0; i< contours.size(); i++ ) // iterate
{
    double a=contourArea( contours[i],false);  //Find the largest area of contour
    if(a>largest_area)
    {
        largest_area=a;
        largest_contour_index=i;
    }

}

drawContours( dst, contours,largest_contour_index, Scalar(255), CV_FILLED, 8, hierarchy ); 
// Draw the largest contour
return dst;
}