Каков наиболее эффективный способ найти ограничительную рамку самого большого блоба в двоичном изображении с помощью OpenCV? К сожалению, OpenCV не имеет специфических функций для обнаружения blob. Должен ли я просто использовать findContours()
и искать самое большое в списке?
OpenCV - найти ограничивающий прямоугольник с наибольшим блобом в бинарном изображении
Ответ 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);
Ответ 4
Возможно, наиболее эффективным способом является использование CvBlobsLib. Вы можете скачать его на http://sourceforge.net/projects/cvblobslib/?source=dlp
Ответ 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;
}