【奇技淫巧】OpenCV中Blob分析的两个关键技巧

发布时间:2023年12月28日

Blob分析

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        minInertiaRatio

OpenCV中Blob检测示例代码如下:

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;

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检测所有的参数就直接失效了,但是官方开发教程示例代码与函数文档都没有说明这点,导致很多新手小白不明所以就直接掉坑了,然后就放弃使用这个函数了。

学习《OpenCV应用开发:入门、进阶与工程化实践》一书
做真正的OpenCV开发者,从入门到入职,一步到位!

全书共计16个章节,重点聚焦OpenCV开发常用模块详解与工程化开发实践,提升OpenCV应用开发能力,助力读者成为OpenCV开发者,同时包含深度学习模型训练与部署加速等知识,帮助OpenCV开发者进一步拓展技能地图,满足工业项目落地所需技能提升。请点下面查看本书目录

《OpenCV应用开发:入门、进阶与工程化实践》

学习课程有专属答疑群
读者专属QQ群 :657875553
进群暗号:OpenCV4读者

文章来源:https://blog.csdn.net/jia20003/article/details/135266011
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。