使用OpenCV查找二进制图像中最大blob的边界框的最有效方法是什么?不幸的是,OpenCV没有特定的blob检测功能。我应该只使用findContours()
并搜索列表中的最大值吗?
答案 0 :(得分:6)
下面。它。是。 (仅供参考:尽量不要懒惰并弄清楚下面我的功能会发生什么。
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;
}
答案 1 :(得分:3)
如果您想使用OpenCV库,请查看OpenCVs SimpleBlobDetector。这是另一个堆栈溢出,显示了它的一个小教程:How to use OpenCV SimpleBlobDetector
这只会给你关键点。你可以使用它作为初始搜索来找到你想要的blob,然后可能在最可能的blob周围使用findContours算法。
您了解有关blob的更多信息,您可以提供参数来过滤掉您不想要的blob。您可能想要测试SimpleBlobDetector的区域参数。可能可以根据图像区域的大小计算面积,然后如果算法没有检测到任何斑点,则迭代地允许更小的斑点。
以下是主要OpenCV文档的链接:http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html#simpleblobdetector
答案 2 :(得分:2)
要查找最大blob的边界框,我使用了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);
答案 3 :(得分:0)
可能最有效的方法是使用CvBlobsLib。 你可以在下载它 http://sourceforge.net/projects/cvblobslib/?source=dlp
答案 4 :(得分:0)
TimZaman,您的代码有错误,但我无法发表评论,所以我开始一个新的正确答案。 这是我的解决方案基于1“和TimZaman的想法:
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;
}
答案 5 :(得分:0)
由于没有人发布完整的OpenCV解决方案,因此这是一种使用阈值+轮廓区域过滤的简单方法
输入图片
最大的斑点/轮廓以绿色突出显示
import cv2
# Load image, grayscale, Gaussian blur, and Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Find contours and sort using contour area
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
for c in cnts:
# Highlight largest contour
cv2.drawContours(image, [c], -1, (36,255,12), 3)
break
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()