【opencv学习】Blob检测斑点

今天学习blob的可用于斑点检测,其实这个斑点只是普通的这么叫法,专业点是的Blob是图像中共享某些共同属性(例如灰度值)的一组连接的像素。

如下图是今天检测的试验图
请添加图片描述

算法过程是:
1:Thresholding(二值化过程):通过对源图像进行阈值化,将源图像转换为若干二值图像,阈值从minThreshold开始。这些阈值通过thresholdStep递增,直到maxThreshold。所以第一个阈值是minThreshold,第二个是minThreshold + thresholdStep,第三个是minThreshold + 2 x thresholdStep,以此类推。

2:Grouping:在每个二值图像中,相互之间的白色像素被组合在一起。我们称这些为二值blobs。

3:Merging:计算二值图像中二值blobs的中心,并合并距离小于minDistBetweenBlobs 的 blobs。

4:Center & Radius Calculation:计算并返回新合并的blobs 的中心和半径。

# 导入库
import cv2
import numpy as np

def cv_show_image(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)  # 等待时间,单位是毫秒,0代表任意键终止
    cv2.destroyAllWindows()

# Blob是图像中共享某些共同属性(例如灰度值)的一组连接的像素。也可以说是斑点之类的。也就是一块相同的区域。
# 这一点在特征检测中也是有提到的。

# 读取图像,并且转为灰度图
img = cv2.imread("images/blob.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 用默认参数设置检测器
detector = cv2.SimpleBlobDetector_create()

# 检测blobs,得到一堆的关键点,之前我们在SIFT特征检测中也是得到了这个信息。
keypoints = detector.detect(gray)
keypoints_array = np.array(keypoints)
print(keypoints_array.shape)
for kp in keypoints:
    print("关键点的位置是: pt[0]:{}\tpt[1]:{}\tangle:{}\tsize:{}".format(
        kp.pt[0], kp.pt[1], kp.angle, kp.size))

# 用红色圆圈画出检测到的blobs
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS 确保圆的大小对应于blob的大小
im_with_keypoints = cv2.drawKeypoints(gray, keypoints_array,
                                      np.array([]), (0, 0, 255),
                                      cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

# 结果显示
cv_show_image("Keypoints", im_with_keypoints)

使用默认参数情况下的效果:
请添加图片描述
发现有一些没有检测上,我们试着更改下参数试一试,比如调整二值化的阈值,调宽一些,面积的范围放宽一些,圆度放宽一点。

# 导入库
import cv2
import numpy as np


def cv_show_image(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)  # 等待时间,单位是毫秒,0代表任意键终止
    cv2.destroyAllWindows()


# 读取图像
im = cv2.imread("images/blob.jpg", cv2.IMREAD_GRAYSCALE)

# 设置SimpleBlobDetector参数
params = cv2.SimpleBlobDetector_Params()

# 改变阈值
# 只会检测minThreshold 和 maxThreshold之间的
params.minThreshold = 10
params.maxThreshold = 240

# 按Color:首先,您需要设置filterByColor = 1。
# 设置blobColor = 0来选择较暗的Blobs,设置blobColor = 255来选择较亮的Blobs。
params.filterByColor = True
params.blobColor = 0

# 根据面积过滤
# 按大小:可以根据大小过滤Blobs,方法是设置参数filterByArea = 1,以及适当的minArea和maxArea值。
# 例如,设置minArea = 100将过滤掉所有像素个数小于100的Blobs。
params.filterByArea = True
params.minArea = 10
params.maxArea = 1000

# 根据Circularity过滤,这个参数是(圆度)
# 这只是测量了这个blob与圆的距离。正六边形的圆度比正方形高。
# 要根据圆度进行过滤,设置filterByCircularity = 1。然后设置适当的minCircularity和maxCircularity值。
params.filterByCircularity = True
params.minCircularity = 0.1

# 根据Convexity过滤,这个参数是(凹凸性)
# 凸性定义为(Blob的面积/它的凸包的面积)。现在,凸包的形状是最紧的凸形状,完全包围了形状。
# 设置filterByConvexity = 1,然后设置0≤minConvexity≤1和maxConvexity(≤1)。
params.filterByConvexity = True
params.minConvexity = 0.14
params.maxConvexity = 1

# 根据Inertia过滤,惯性比
# 它衡量的是一个形状的伸长程度。例如,对于圆,这个值是1,对于椭圆,它在0和1之间,对于直线,它是0。
# 初步可以认为是外接矩形的长宽比,圆的外接矩形的长宽相等,椭圆是有长短轴,短轴长度除以长轴长度,介于0~1
# 直线可以认为没有宽度,因此是0
params.filterByInertia = True
params.minInertiaRatio = 0.01

# 创建一个带有参数的检测器
detector = cv2.SimpleBlobDetector_create(params)

# 检测blobs
keypoints = detector.detect(im)
keypoints_array = np.array(keypoints)
print(keypoints_array.shape)

# 用红色圆圈画出检测到的blobs
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS 确保圆的大小对应于blob的大小
im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0, 0, 255),
                                      cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

# 结果显示
cv_show_image("Keypoints", im_with_keypoints)

调整完参数的效果是:
请添加图片描述
本文学习自
https://blog.csdn.net/weixin_43229348/article/details/120448954

猜你喜欢

转载自blog.csdn.net/qq_29367075/article/details/123467905