
BLOB是图像中灰度块的一种专业称呼,更加变通一点的可以说它跟我们前面二值图像分析的联通组件类似,通过特征提取实现常见的各种灰度BLOB对象组件检测与分离。使用该检测器的时候,可以根据需要输入不同参数,得到的结果跟输入的参数息息相关。

Blob分析函数与演示
OpenCV中的Blob分析函数为SimpleBlobDetector,OpenCV中支持实现常见的BLOB分析过滤,如下所示:
-根据BLOB面积过滤
-根据灰度/颜色值过滤
-根据圆度过滤
-根据长轴与短轴过滤
-根据凹凸进行过滤对应的参数列表如下:
SimpleBlobDetector::Params::Params()
bool filterByArea
bool filterByCircularity
bool filterByColor
bool filterByConvexity
bool filterByInertia
float maxArea
float maxCircularity
float maxConvexity
float maxInertiaRatio
float maxThreshold
float minArea
float minCircularity
float minConvexity
float minDistBetweenBlobs
float minInertiaRatioOpenCV中Blob检测示例代码如下:
#include "opencv2/opencv.hpp"
#include <iostream>
usingnamespace cv;
usingnamespacestd;
int main(int argc, char** argv)
{
// 加载图像
Mat src = imread("D:/lena.jpg");
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
cv::imshow("输入图像", src);
// 初始化参数设置
SimpleBlobDetector::Params params;
params.minThreshold = 10;
params.maxThreshold = 240;
params.filterByArea = true;
params.minArea = 50;
params.filterByCircularity = true;
params.minCircularity = 0.1;
params.filterByConvexity = true;
params.minConvexity = 0.5;
params.filterByInertia = true;
params.minInertiaRatio = 0.5;
// 创建BLOB Detetor
Ptr<SimpleBlobDetector> detector = SimpleBlobDetector::create(params);
// BLOB分析与显示
Mat result;
vector<KeyPoint> keypoints;
detector->detect(gray, keypoints);
for (auto kpt : keypoints) {
std::cout << "key point radius: " << kpt.size << std::endl;
cv::circle(src, kpt.pt, 2, cv::Scalar(0, 255, 0), 2, 8, 0);
cv::circle(src, kpt.pt, kpt.size/2, cv::Scalar(255, 0, 255), 3, 8, 0);
}
imshow("Blob检测-OpenCV学堂", src);
waitKey(0);
}演示效果如下:

特殊使用技巧
SimpleBlobDetector 函数有两个很诡异的地方。
第一个是实现的默认参数支持与参数检查
OpenCV中SimpleBlobDetector函数默认的参数值如下:
thresholdStep = 10;
minThreshold = 50;
maxThreshold = 220;
minRepeatability = 2;
minDistBetweenBlobs = 10;
filterByColor = true;
blobColor = 0;
filterByArea = true;
minArea = 25;
maxArea = 5000;
filterByCircularity = false;
minCircularity = 0.8f;
maxCircularity = std::numeric_limits<float>::max();
filterByInertia = true;
//minInertiaRatio = 0.6;
minInertiaRatio = 0.1f;
maxInertiaRatio = std::numeric_limits<float>::max();
filterByConvexity = true;
//minConvexity = 0.8;
minConvexity = 0.95f;
maxConvexity = std::numeric_limits<float>::max();
collectContours = false;每次执行之前都会进行断言检查,但是OpenCV中同时提供了是否启用Blob各种过滤开关选项,但是无论开关选项是否启用,这个断言检查都是检查全部属性值,这个就导致你设置选项为false的时候,必须填写对应选项的选项值,否则就无法执行Blob检测函数。对应的源码文件 blobdetector.cpp 发现了这段代码作为佐证:
static void validateParameters(const SimpleBlobDetector::Params& p)
{
if (p.thresholdStep <= 0)
CV_Error(Error::StsBadArg, "thresholdStep>0");
if (p.minThreshold > p.maxThreshold || p.minThreshold < 0)
CV_Error(Error::StsBadArg, "0<=minThreshold<=maxThreshold");
if (p.minDistBetweenBlobs <=0 )
CV_Error(Error::StsBadArg, "minDistBetweenBlobs>0");
if (p.minArea > p.maxArea || p.minArea <=0)
CV_Error(Error::StsBadArg, "0<minArea<=maxArea");
if (p.minCircularity > p.maxCircularity || p.minCircularity <= 0)
CV_Error(Error::StsBadArg, "0<minCircularity<=maxCircularity");
if (p.minInertiaRatio > p.maxInertiaRatio || p.minInertiaRatio <= 0)
CV_Error(Error::StsBadArg, "0<minInertiaRatio<=maxInertiaRatio");
if (p.minConvexity > p.maxConvexity || p.minConvexity <= 0)
CV_Error(Error::StsBadArg, "0<minConvexity<=maxConvexity");
}第二个是现实的默认输入图像的背景必须是白色
如果是黑色背景图像输入,Blob检测所有的参数就直接失效了,但是官方开发教程示例代码与函数文档都没有说明这点,导致很多新手小白不明所以就直接掉坑了,然后就放弃使用这个函数了。