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

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

做真正的OpenCV开发者,从入门到入职,一步到位!

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读者

  • 19
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
数据结构能够判断是否存在环的方法之一是使用快慢指针法。该方法适用于链表和图等数据结构。快慢指针法的基本思想是使用两个指针,一个指针每次移动一个节点,而另一个指针每次移动两个节点。如果存在环,则两个指针最终会相遇。 另一种方法是使用深度优先搜索(DFS)或广度优先搜索(BFS)来遍历图或树。在遍历过程,如果遇到已经访问过的节点,则说明存在环。 综上所述,数据结构能够判断是否存在环的方法包括快慢指针法和深度优先搜索或广度优先搜索。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [算法数据结构有哪些奇技淫巧?](https://blog.csdn.net/lyshark_lyshark/article/details/126792526)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [JavaScript版数据结构与算法](https://blog.csdn.net/qq_46345868/article/details/124532434)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gloomyfish

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值