
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类型。 · 按颜色:首先,您需要设置 filterByColor =1。设置 blobColor = 0以选择较暗的blob,将 blobColor = 255设置为较浅的blob。 · 按大小:通过设置参数filterByArea = 1以及minArea 和maxArea的适当值, 可以基于大小过滤blob 。例如,设置 minArea = 100将滤除所有少于100个像素的斑点。 · 按形状:现在形状具有三个不同的参数。
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::max(); filterByInertia = true; #斑点惯性率的限制变量 minInertiaRatio = 0.1f; #斑点的最小惯性率 maxInertiaRatio = std::numeric_limits::max(); #斑点的最大惯性率 filterByConvexity = true; #斑点凸度的限制变量 minConvexity = 0.95f; #斑点的最小凸度 maxConvexity = std::numeric_limits::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()关闭所有图像窗口。

代码截图
|