Python代码使用OpenCV进行Blob检测

blob

什么是Blob?

blob是图像中一组共享的区域,它们具有一些共同的属性(例如灰度值,形状,尺寸等)blob检测的目的是识别并标记一些特定区域,blob检测在自动化工业领域比较常见。

OpenCV提供了一种方便的方法来检测blob并根据不同的特征对其进行过滤。那就是

SimpleBlobDetector检测算法

OpenCV实现的算法如下:

  • 1. 对[minThreshold,maxThreshold)区间,以thresholdStep为间隔,做多次二值化。
  • 2. 对每张二值图片,使用提取连通域并计算每一个连通域的中心。
  • 3. 根据2得到的中心,全部放在一起。一些很接近的点[由theminDistBetweenBlobs控制多少才算接近]被归为一个group,对应一个bolb特征..
  • 4. 从3得到的那些点,估计最后的blob特征和相应半径,并以key points返回。

首先我们先按照默认的配置建立一个简单的blob检测实例

import cv2
import numpy as np;
im = cv2.imread("blob_detection.jpg", cv2.IMREAD_GRAYSCALE)
detector = cv2.SimpleBlobDetector_create()
keypoints = detector.detect(im)
with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]),
(0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow("Keypoints", with_keypoints)
cv2.waitKey(0)

首先我们读入一张需要检测的图片

并使用
cv2.SimpleBlobDetector_create检测函数建立一个检测器,这里需要注意的是CV2 3.0以前的版本,请使用cv2.SimpleBlobDetector函数,这里的cv2.IMREAD_GRAYSCALE便是打开图片的时候并转换成灰度空间,这个跟函数cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)实现的功能一样,只是2种不同的写法。

然后使用detector.detect函数,对图片进行检测,函数返回检测到的关键点

最后使用cv2.drawKeypoints函数画出图片中检测到的blob即可

cv2.drawKeypoints()函数主要包含五个参数:

· image:也就是原始图片
· keypoints:从原图中获得的关键点,这也是画图时所用到的数据
· outputimage:输出
· color:颜色设置,通过修改(b,g,r)的值,更改画笔的颜色,b=蓝色,g=绿色,r=红色。
· flags:绘图功能的标识设置,主要包括如下:
cv2.DRAW_MATCHES_FLAGS_DEFAULT, 
  cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
  cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG,
  cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS

代码截图

SimpleBlobDetector基于以下描述的相当简单的算法。该算法由不同的参数控制

blob

阈值处理:通过使用以minThreshold开始的阈值对源图像进行阈值处理,将源图像转换为多个二进制图像 。这些阈值以thresholdStep递增, 直到 maxThreshold。

因此,第一个阈值为 minThreshold, 

第二个阈值为 minThreshold + thresholdStep,

第三个阈 值为 minThreshold + 2 x thresholdStep,依此类推。

1. 分组: 在每个二进制图像中,连接的白色像素被分组在一起。我们称这些二进制斑点为一。

2. 合并 :计算二进制图像中二进制斑点的中心,并合并比minDistBetweenBlob 更近的斑点 。

3. 中心和半径计算: 计算并返回新合并的Blob的中心和半径。

按颜色,大小和形状过滤斑点

可以设置SimpleBlobDetector的参数以过滤所需的Blob类型。

  1. · 按颜色: 首先,您需要设置 filterByColor =1。设置 blobColor = 0以选择较暗的blob,将 blobColor = 255设置为较浅的blob。 
  2. · 按大小: 通过设置参数filterByArea = 1以及minArea 和maxArea的适当值, 可以基于大小过滤blob 。例如,设置 minArea = 100将滤除所有少于100个像素的斑点。
  3. · 按形状: 现在形状具有三个不同的参数。

1. 圆度: 这只是测量斑点距圆的距离。例如,正六边形的圆度比正方形大。要按圆度过滤,请设置 filterByCircularity =1。然后为minCircularity 和maxCircularity设置适当的值。 圆度定义为。

圆度

这意味着圆的圆度为1,正方形的圆度为0.785,依此类推。

圆度

2. 凸性: 一张图片值一千字。凸度定义为(斑点的面积/凸包的面积)。现在,形状的凸包是完全封闭该形状的最紧密的凸形。由凸滤波器,集 filterByConvexity = 1 ,然后设置0≤ minConvexity ≤1和maxConvexity(≤1) 

凸性

3. 惯性比:对于一个圆,该值是1,对于椭圆它是0和1之间,而对于线是0。要通过过滤器惯量比,设置 filterByInertia = 1 , 并设置0≤ minInertiaRatio ≤1和 maxInertiaRatio (≤1 )适当地。

惯性比

通过以上参数的设计,我们可以选择符合我们需求的blob值进行检测

import cv2
import numpy as np
im = cv2.imread("blob.jpg", cv2.IMREAD_GRAYSCALE)
params = cv2.SimpleBlobDetector_Params()
# 设置阈值
params.minThreshold = 10
params.maxThreshold = 200
# 设置选择区域
params.filterByArea = True
params.minArea = 1500
# 设置圆度
params.filterByCircularity = True
params.minCircularity = 0.1
# 设置凸度
params.filterByConvexity = True
params.minConvexity = 0.87
# 设置惯性比
params.filterByInertia = True
params.minInertiaRatio = 0.01
detector = cv2.SimpleBlobDetector_create(params)
keypoints = detector.detect(im)
with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]),
(0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow("Keypoints",with_keypoints)
cv2.waitKey(0)

首先使用
cv2.SimpleBlobDetector_Params函数对不同参数进行调整,其主要参数如下:

SimpleBlobDetector::Params()
{    thresholdStep = 10;    #二值化的阈值步长,即公式1的t    
minThreshold = 50;   #二值化的起始阈值,即公式1的T1   
 maxThreshold = 220;    #二值化的终止阈值,即公式1的T2    #重复的最小次数,只有属于灰度图像斑点的那些二值图像斑点数量大于该值时,该灰度图像斑点才被认为是特征点    
minRepeatability = 2;       #最小的斑点距离,不同二值图像的斑点间距离小于该值时,被认为是同一个位置的斑点,否则是不同位置上的斑点    
minDistBetweenBlobs = 10;    
 filterByColor = true;    #斑点颜色的限制变量    
blobColor = 0;    #表示只提取黑色斑点;如果该变量为255,表示只提取白色斑点    
 filterByArea = true;    #斑点面积的限制变量    
minArea = 25;    #斑点的最小面积   
 maxArea = 5000;    #斑点的最大面积    
 filterByCircularity = false;    #斑点圆度的限制变量,默认是不限制    
minCircularity = 0.8f;    #斑点的最小圆度    #斑点的最大圆度,所能表示的float类型的最大值   
 maxCircularity = std::numeric_limits<float>::max();     
filterByInertia = true;    #斑点惯性率的限制变量    
minInertiaRatio = 0.1f;    #斑点的最小惯性率   
 maxInertiaRatio = std::numeric_limits<float>::max();    #斑点的最大惯性率     
filterByConvexity = true;    #斑点凸度的限制变量   
minConvexity = 0.95f;    #斑点的最小凸度    
maxConvexity = std::numeric_limits<float>::max();    #斑点的最大凸度}

首先我们定义好不同的参数,包含:阈值,尺寸,圆度,凸度,惯性比等参数,这些参数可以过滤到我们不需要的blob,运行以上代码便可以查看结果

blob检测

代码截图

一般blob的主要应用于工业领域,比如产品的坏点检测,自动化产线上的产品尺寸大小检测,产品方向,位置,角度检测等等

这就需要使用视频实时检测

Blob的视频实时检测

import cv2
import numpy as np
import time
params = cv2.SimpleBlobDetector_Params()
# 设置阈值
params.minThreshold = 10
params.maxThreshold = 200
# 设置选择区域
params.filterByArea = True
params.minArea = 1500
# 设置圆度
params.filterByCircularity = True
params.minCircularity = 0.1
# 设置凸度
params.filterByConvexity = True
params.minConvexity = 0.87
# 这种惯性比
params.filterByInertia = True
params.minInertiaRatio = 0.01
detector = cv2.SimpleBlobDetector_create(params)

首先安装图片检测原理图,设置SimpleBlobDetector的检测参数,并初始化SimpleBlobDetector检测函数

代码截图

初始化完成后,便可以打开摄像头,进行视频的实时检测

capture = cv2.VideoCapture(0)
time.sleep(2)
cv2.namedWindow('blob',cv2.WINDOW_AUTOSIZE)

while(1):
  ret, frame = capture.read()
  im = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  keypoints = detector.detect(im)
  with_keypoints = cv2.drawKeypoints(frame, keypoints, np.array([]),
  (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
  cv2.imshow("Keypoints",with_keypoints)
  if cv2.waitKey(5)&0xFF == ord('q'):
    break
capture.release()
cv2.destroyAllWindows()

这里需要注意的是cv2.VideoCapture(0)打开默认的摄像头,这里若想要检测视频,可以输入视频的绝对路径地址

1、frame = cv2.VideoCapture(0)
VideoCapture()中参数是0,表示打开笔记本的内置摄像头,参数是视频文件路径则打开视频,
如frame= cv2.VideoCapture("../test.avi")
2、ret,frame = cap.read()
cap.read()按帧读取视频,ret,frame是获cap.read()方法的两个返回值。
其中ret是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,
它的返回值就为False。frame就是每一帧的图像,是个三维矩阵。
3、cv2.waitKey(1),waitKey()方法本身表示等待键盘输入,
参数是1,表示延时1ms切换到下一帧图像,对于视频而言;
参数为0,如cv2.waitKey(0)只显示当前帧图像,相当于视频暂停,等待用户输入任意键;
参数过大如cv2.waitKey(1000),会因为延时过久而卡顿感觉到卡顿。
当键盘输入q字母时,退出程序运行
4、调用release()释放摄像头,调用destroyAllWindows()关闭所有图像窗口。

代码截图

https://m.toutiao.com/is/iLjn9d26/ 人工智能研究所: 视频动画详解Transformer模型–Attention is all you need.