B13 - 图像处理 - Blob 检测与提取

Blob 检测原理以及评估指标

什么是 Blob 检测?

  • 19-Blob检测与提取-20230704211650
  • Blob 在计算机视觉中通常指的是图像中的一块连续区域,这些区域具有某些共同的属性,比如颜色或灰度值。OpenCV 提供了 SimpleBlobDetector 类,它可以用于检测图像中的 blob,并根据不同的特征对它们进行过滤
  • Blob 检测指识别和标记 blob 区域,目前有 3 种方法进行斑点检测:高斯拉普拉斯 (LoG)、高斯差分 (DoG) 和黑森行列式 (DoH)
    1
    2
    3
    4
    5
    6
    7
    im = cv2.imread("blob.jpg", cv2.IMREAD_GRAYSCALE)
    # 使用默认参数设置检测器.
    detector = cv2.SimpleBlobDetector_create()
    # 检测blob.
    keypoints = detector.detect(im)
    # 使用圆形绘制斑点.
    im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

Blob 检测的原理?

  • (1) 多次二值化:对 minThreshold,maxThreshold) 区间,以 thresholdStep 为间隔,做多次二值化
  • (2) 分组: 在每个二进制图像中,连接的白色像素被分组在一起。我们称这些二进制斑点为二进制斑点
  • (3) 合并: 计算二进制图像中二进制斑点的中心,并合并比 minDistBetweenBlob 更近的斑点
  • (4) 中心及半径计算: 计算并返回新合并的 Blob 的中心和半径

OpenCV 的 Bolo 检测 “颜色 (blobColor)” 设置方法?

  • 默认检测黑色点,如果要检测白色的点请设置 blobColor 为 true,并且 color 数值是 255.

OpenCV 的 Bolo 检测 “阈值 (minThreshold/maxThreshold/thresholdStep)” 设置方法?

  • 设置二值化阈值区间,其中 thresholdStep 为阈值步进区间,用于生成多个二值图

OpenCV 的 Bolo 检测 “面积 (minArea/maxArea)” 设置方法?

  • 基于大小过滤 blob 。例如,设置 minArea = 100 将滤除所有少于 100 个像素的斑点

OpenCV 的 Bolo 检测 “凸性 (minConvexity/maxConvexity)” 设置方法?

  • 斑点的面积 / 凸包的面积,取值范围 [0-1]

OpenCV 的 Bolo 检测 “圆度 (minCircularity/maxCircularity)” 设置方法?

  • 表示斑点距圆的距离,使用斑点面积与周长的平方之比计算,具有平移、尺度、旋转不变性
  • 4πArea(perimeter)2\frac{4\pi\,A r e a}{(p e r i m e t e r)_{-}^{2}}

  • 圆的圆度为 1,正方形的圆度为 0.785

OpenCV 的 Bolo 检测 “惯性比 (minInertiaRatio/maxInertiaRatio)” 设置方法?

  • 衡量形状的伸长程度,相当于(短轴 / 长轴),例如对于一个圆,则惯性比是 1,对于椭圆的惯性比在 0 和 1 之间,而对于线是 0; 0≤ minInertiaRatio ≤1 , maxInertiaRatio ≤ 1

OpenCV 的 Bolo 检测的 minDistBetweenBlobs、minRepeatability 参数的含义?

  • minDistBetweenBlobs: 最小的斑点距离,不同二值图像的斑点间距离小于该值时,被认为是同一个位置的斑点,否则是不同位置上的斑点,默认 10
  • minRepeatability: 重复的最小次数,只有属于灰度图像斑点的那些二值图像斑点数量大于该值时,该灰度图像斑点才被认为是特征点,默认 2

什么是 Blob 提取?

  • 19-Blob检测与提取-20230704211652
  • 连接组件标记(CCL)、连接组件分析(CCA)、Blob 提取、区域标记、斑点发现或区域提取是图论的一种算法应用,其中连接组件的子集基于给定的启发式方法被唯一标记。原理参考如何认识 OpenCV 的线型 lineType
  • 通常使用 cv 2. ConnectedComponentsWithStats 来提取图像中的 Blob 区域
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    img = cv2.imread("blob.png")
    # 中值滤波,去噪
    img = cv2.medianBlur(img, 3)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 阈值分割得到二值化图片
    ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    # ret, binary = cv2.threshold(gray, 50, 255, cv2.THRESH_BINARY)
    # 腐蚀操作
    kernel2 = cv2.getStructuringElement(cv2.MORPH_ERODE, (11, 11))
    bin_clo = cv2.erode(binary, kernel2, iterations=3)
    # 连通域分析
    num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(bin_clo, connectivity=4)
    # 不同的连通域赋予不同的颜色
    output = np.zeros((img.shape[0], img.shape[1], 3), np.uint8)
    for i in range(1, num_labels):
    mask = labels == i
    output[:, :, 0][mask] = np.random.randint(0, 255)
    output[:, :, 1][mask] = np.random.randint(0, 255)
    output[:, :, 2][mask] = np.random.randint(0, 255)