opencv SimpleBlobDetector blob分析斑点检测原理详解
opencv SimpleBlobDetector blob分析斑点检测原理详解
文章目录
- 概念
- 一、SimpleBlobDetector算法原理
- 二、opencv 类接口原型:
- 三、代码示例:
- 四、运行效果:
概念
Blob是图像中具有某些共同属性(如灰度值、圆度等如下图所示属性)的一组连通像素。
一、SimpleBlobDetector算法原理
SimpleBlobDetector从图像中提取blobs的算法流程如下:
- 根据阈值步距“thresholdStep”递增,从最小阈值‘minThreshold“(包含)到最大阈值maxThreshold(排除)计算几个阈值,第一个阈值minThreshold,第二个是minThreshold+ thresholdStep,…以此类推。将这些阈值分别应用于源图像转换为几张二值图像。
- 通过findContours算子从每幅二值图像中提取连通分量并计算它们中心位置。
- 由团块之间的最小距离minDistBetweenBlobs参数控制。将几个二值图像的团块中心坐标进行分组。闭合中心形成一组。
- 从组中,估计斑点的最终中心和它们的半径,并返回点的位置和大小。
- 最后对返回的blob执行特征过滤:
(1):颜色过滤:使用blobColor = 0提取亮色斑点,使用blobColor = 255提取暗色斑点。将二值化图像斑点中心的灰度值和blobColor比较 。如果它们不一致,则将该斑点过滤掉。
(2):面积过滤:提取面积在minArea(包含)和maxArea(不包含)之间的blob。
(3): 圆度过滤:提取的圆度介于minCircularity(包含)和maxCircularity(不包含)之间的Blob。
(4):惯性比过滤:提取惯量介于minInertiaRatio(包含)和maxInertiaRatio(不包含)之间的blob
(5): 凸性过滤:提取凸性介于minConvexity(包含)和maxConvexity(不包含)之间的blob。
二、opencv 类接口原型:
class CV_EXPORTS_W SimpleBlobDetector : public Feature2D
{
public:struct CV_EXPORTS_W_SIMPLE Params{CV_WRAP Params();CV_PROP_RW float thresholdStep;CV_PROP_RW float minThreshold;CV_PROP_RW float maxThreshold;CV_PROP_RW size_t minRepeatability;CV_PROP_RW float minDistBetweenBlobs;CV_PROP_RW bool filterByColor;CV_PROP_RW uchar blobColor;CV_PROP_RW bool filterByArea;CV_PROP_RW float minArea, maxArea;CV_PROP_RW bool filterByCircularity;CV_PROP_RW float minCircularity, maxCircularity;CV_PROP_RW bool filterByInertia;CV_PROP_RW float minInertiaRatio, maxInertiaRatio;CV_PROP_RW bool filterByConvexity;CV_PROP_RW float minConvexity, maxConvexity;void read( const FileNode& fn );void write( FileStorage& fs ) const;};CV_WRAP static Ptr<SimpleBlobDetector>create(const SimpleBlobDetector::Params ¶meters = SimpleBlobDetector::Params());CV_WRAP virtual String getDefaultName() const CV_OVERRIDE;
};
三、代码示例:
//SimpleBlobDetector
cv::SimpleBlobDetector::Params pBLOBDetector;
cv::Mat src;
int iThStep = 10;
int iMinth = 10;
int iMaxth = 200;
int iMinBt = 10;
int iMinar = 10;
int iMaxar = 1500;
int iMinCir = 0;
int iMinIne = 0;
int iMinCon = 0;void detect(int ,void *)
{pBLOBDetector.thresholdStep = iThStep;pBLOBDetector.minThreshold = iMinth;pBLOBDetector.maxThreshold = iMaxth;pBLOBDetector.minRepeatability = 2;pBLOBDetector.minDistBetweenBlobs = iMinBt;pBLOBDetector.filterByColor = true;pBLOBDetector.blobColor = 0;//斑点面积pBLOBDetector.filterByArea = true;pBLOBDetector.minArea = iMinar;pBLOBDetector.maxArea = iMaxar;//斑点圆度pBLOBDetector.filterByCircularity = true;pBLOBDetector.minCircularity = iMinCir *0.01;pBLOBDetector.maxCircularity = (float)3.40282e+038;//斑点惯性率pBLOBDetector.filterByInertia = true;pBLOBDetector.minInertiaRatio = iMinIne * 0.01;pBLOBDetector.maxInertiaRatio = (float)3.40282e+038;//斑点凸度pBLOBDetector.filterByConvexity = true;pBLOBDetector.minConvexity = iMinCon * 0.01;pBLOBDetector.maxConvexity = (float)3.40282e+038;//*用参数创建对象cv::Ptr<cv::SimpleBlobDetector> blob = cv::SimpleBlobDetector::create(pBLOBDetector);//Ptr<SimpleBlobDetector> blob=SimpleBlobDetector::create();//默认参数创建//*blob检测vector<cv::KeyPoint> key_points;//Mat dst;//cvtColor(src, dst, COLOR_RGB2GRAY);blob->detect(src, key_points);cv::Mat outImg;//src.copyTo(outImg);//绘制结果cv::drawKeypoints(src, key_points, outImg, cv::Scalar(0, 0, 255));cv::imshow("blob", outImg);
}void test_SimpleBlobDetector()
{//cv::Mat src;src = cv::imread("D:\\QtProject\\Opencv_Example\\SimpleBlobDetector\\blobs.png", cv::IMREAD_GRAYSCALE);if (src.empty()) {cout << "Cannot load image" << endl;return;}cv::imshow("src", src);cv::namedWindow("Detect window", cv::WINDOW_NORMAL);cv::createTrackbar("最小圆度", "Detect window", &iMinCir, 100, detect);cv::createTrackbar("最小惯性率", "Detect window", &iMinIne, 100, detect);cv::createTrackbar("最大凸度", "Detect window", &iMinCon, 100, detect);cv::createTrackbar("阈值步距", "Detect window", &iThStep, 100, detect);cv::createTrackbar("最小阈值", "Detect window", &iMinth, 255, detect);cv::createTrackbar("最大阈值", "Detect window", &iMaxth, 255, detect);cv::createTrackbar("最小距离", "Detect window", &iMinBt, 255, detect);cv::createTrackbar("最小面积", "Detect window", &iMinar, 1000, detect);cv::createTrackbar("最大面积", "Detect window", &iMaxar, 5000, detect);
}