原理
首先通过一系列连续的阈值把输入的灰度图像转换为一个二值图像的集合,阈值范围为[T1,T2],步长为t,则所有阈值为:
第二步是利用Suzuki提出的算法通过检测每一幅二值图像的边界的方式提取出每一幅二值图像的连通区域,我们可以认为由边界所围成的不同的连通区域就是该二值图像的斑点;【不同的区域就像是不同的斑点】
第三步是根据所有二值图像斑点的中心坐标对二值图像斑点进行分类,从而形成灰度图像的斑点,属于一类的那些二值图像斑点最终形成灰度图像的斑点,具体来说就是,灰度图像的斑点是由中心坐标间的距离小于阈值Tb的那些二值图像斑点所组成的,即这些二值图像斑点属于该灰度图像斑点;
最后就是确定灰度图像斑点的信息——位置和尺寸。位置是属于该灰度图像斑点的所有二值图像斑点中心坐标的加权和,即公式2,权值q等于该二值图像斑点的惯性率的平方,它的含义是二值图像的斑点的形状越接近圆形,越是我们所希望的斑点,因此对灰度图像斑点位置的贡献就越大。尺寸则是属于该灰度图像斑点的所有二值图像斑点中面积大小居中的半径长度。
最后就是确定灰度图像斑点的信息——位置和尺寸。位置是属于该灰度图像斑点的所有二值图像斑点中心坐标的加权和,二值图像的斑点的形状越接近圆形,越是我们所希望的斑点,因此对灰度图像斑点位置的贡献就越大。
不是所有的二值图像的连通区域都认为是二值图的斑点,会通过一定的限制。如面积、圆度【越接近0越像圆】、偏心率、凸度(凹凸)
凸度:凸形图指的是图形的所有部分都在由该图形切线所围成的区域的内部
圆度:C = 4πS/p^2
S表示面积,p表示周长
代码
#!/usr/bin/python
# Standard imports
import cv2
import numpy as np;
# Read image
im = cv2.imread("blob.jpg", cv2.IMREAD_GRAYSCALE)
# Setup SimpleBlobDetector parameters.
params = cv2.SimpleBlobDetector_Params()
# 设置阈值#影响颜色问题
params.minThreshold = 10
params.maxThreshold = 500
# 设置面积
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
# cv2版本
ver = (cv2.__version__).split('.')
if int(ver[0]) < 3 :
detector = cv2.SimpleBlobDetector(params)
else :
detector = cv2.SimpleBlobDetector_create(params)
# 检测图像
keypoints = detector.detect(im)
# 斑点红色(0,0,255)
# DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS会一种丰富的方式画出来
#cv2.drawKeypoints()画点,斑点在图中的表示
#画带有关键点的图像
im_with_keypoints = cv2.drawKeypoints(im,keypoints,np.array([]),(0,255,0),cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# 显示斑点
cv2.imshow("Keypoints", im_with_keypoints)
cv2.waitKey(0)