Python基于opencv的blob算法实现

       最近也是想试试blob算法检测个东西。发现Python方面讲这个的真不多,几乎都是说的算法原理,这里给出Python3代码,与 效果图。copy了别人的成果,代码什么的也是,原链接是:点击打开链接。这个网站是learnopencv,全英文的,无障碍的可以看看,我是为了自己学习整理了一下,如有错漏,欢迎指正。

1.什么是Blob?

       像素是图像中的一组连接像素,它们共享一些公共属性(例如灰度值)。在上面的图像中,暗连接区域是斑点,而斑点检测的目标是识别和标记这些区域。这个算法说白了就是检测图像的斑点,“一坨一坨”的异于周围背景的东西,代表的是一些“不同”的区域。

2. Blob检测是如何实现的?

      simpleblobdetector,顾名思义,就像下面描述的那样,是一个非常简单的算法。该算法由一些参数控制(如下所示),并具有以下步骤。从上往下来了解参数是如何设置的。

1.Thresholding :

      首先进行阈值分割。从设置的最小阈值minthreshold参数开始将源图分割为几个二值图。这些阈值是通过设置的步长thresholdStep 逐渐递增的,知道达到设置好的最大阈值maxThreshold参数。所以第一个阈值是minthreshold,第二个阈值是minthreshold+thresholdStep ,第三个阈值是minthreshold+2×thresholdStep ,以此类推。

2.Grouping:

      在每个二值图像中,连接的白像素被分组在一起。让我们调用这些斑点。

3.Merging  :

       合并。计算这些二值图中的斑点的中心,并且将相互之间距离小于设置的minDistBetweenBlobs 的斑点合并成一个

4.Center & Radius Calculation:

      中心和半径的计算。计算这些合并后的斑点的中心和半径,并返回。

3.通过颜色,大小和形状过滤这些斑点

可以通过设置SimpleBlobDetector 函数的参数对斑点进行过滤,来获得我们所需要的斑点

  • 通过颜色:【这个功能可能有点问题(当然博主不是很清楚这个问题,没试过),作者检查了这个代码,发现他有逻辑上的问题(也不知道他用的什么版本的opencv,是不是真有这个问题,官方是否已经对此进行了优化,知道的小伙伴可以告诉我)】。首先,需要设置filterByColor = 1,设置blobColor = 0来选择暗淡区域(应该就是黑色)的斑点,或者是blobColor = 255(来选择亮区域应该就是白色)的斑点。
  • 通过大小:可以通过将参数filterByArea =1,并且给minAreamaxArea设置恰当的参数。比如:将minArea=100,这样会将所有斑点里像素小于100的过滤掉。
  • 通过形状:现在形状有三种参数:
  1. 圆(Circularity  :这个仅仅衡量斑点和圆有多相似。比如:正六边形比正方形有更高的圆度。通过类圆性来过滤,可以设置filterByCircularity = 1,然后给minCircularity 和maxCircularity设置恰当的参数。类圆性定义如下:也就是(4π×面积)/(周长的平方)。也就是说圆的类圆性是1,正方形的类圆性是0.785等等。
  2. 凸性(Convexity ):凸性的定义是(斑点的面积/斑点凸包的面积)。一个形状的凸包是严格凸的形状,并且完全封闭(这玩意在手势识别里还是蛮好用的,不懂得可以去了解下)。将filterByConvexity =1,接下来设置 0 ≤ minConvexity ≤ 1maxConvexity ( ≤ 1) 。
  3. 惯量比(Inertia Ratio):不要被此吓倒(其实博主看的时候也不知道是啥)。数学经常使用一些迷惑性的语言去描述一些非常简单的东西。你所需要知道的是,这个测量了一个形状有多长。例如:对于一个圆,这个值是1,对于一个椭圆,它在0到1之间,对于一条直线,它是0。想要通过惯量比来过滤,需要设置filterByInertia =1, 0 ≤ minInertiaRatio ≤ 1,并且适当的设置参数maxInertiaRatio (≤ 1 )的值。

4.python代码实现

#!/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()

# Change thresholds
params.minThreshold = 10
params.maxThreshold = 200


# Filter by Area.
params.filterByArea = True
params.minArea = 1500

# Filter by Circularity
params.filterByCircularity = True
params.minCircularity = 0.1

# Filter by Convexity
params.filterByConvexity = True
params.minConvexity = 0.87
    
# Filter by Inertia
params.filterByInertia = True
params.minInertiaRatio = 0.01

# Create a detector with the parameters
ver = (cv2.__version__).split('.')
if int(ver[0]) < 3 :
	detector = cv2.SimpleBlobDetector(params)
else : 
	detector = cv2.SimpleBlobDetector_create(params)


# Detect blobs.
keypoints = detector.detect(im)

# Draw detected blobs as red circles.
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures
# the size of the circle corresponds to the size of blob

im_with_keypoints = cv2.drawKeypoints(im, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

# Show blobs
cv2.imshow("Keypoints", im_with_keypoints)
cv2.waitKey(0)

效果图如下:




猜你喜欢

转载自blog.csdn.net/dz4543/article/details/79897763