如何调整OpenCV参数以检测黑色背景上的白色Blob?
解决黑底白Blob检测失败的问题
针对你的代码和测试场景,以下是具体的修改方案和原因说明:
核心问题与修改点
- 检测方向错误:OpenCV的
SimpleBlobDetector默认检测**深色Blob(值为0)**在浅色背景上,而你的场景是白色Blob(值为255)在黑色背景,需添加pp.blobColor = 255指定检测浅色Blob。 - 面积阈值过高:测试图中的Blob实际面积远小于你设置的
minArea=100,需调低该值(比如设为10)。 - 圆形度过滤过严:
minCircularity=0.9要求Blob接近完美圆形,测试图中的Blob可能达不到这个标准,可调低至0.5或暂时关闭该过滤项。 - 图像转换错误:
cv2.cvtColor(img1, cv2.CV_8UC1)是错误用法,CV_8UC1是数据类型而非颜色转换标志。如果plt.imread读入的是RGB图,应使用cv2.COLOR_RGB2GRAY转换为灰度图;如果是单通道灰度图,可直接跳过该转换。
修改后的完整代码
import matplotlib.pyplot as plt import numpy as np import cv2 def normalizeImage(image): print("Normalizing image..") # 处理plt.imread可能返回的0-1浮点数图像 if image.dtype == np.float32 or image.dtype == np.float64: image = (image * 255).astype(np.uint8) min_val = np.min(image) image = image - min_val # 确保值为正 max_val = np.max(image) if max_val == 0: return image div = max_val / 255 image_8u = np.uint8(np.round(image / div)) return image_8u def detectBlobs(dustImage): print("Detecting blobs...") pp = cv2.SimpleBlobDetector_Params() # 关键:设置检测白色Blob(255) pp.blobColor = 255 # 面积过滤:调低minArea适配测试图Blob大小 pp.filterByArea = True pp.minArea = 10 # 根据实际Blob大小调整,测试图中Blob面积约20左右 pp.maxArea = 1000 # 可根据需求设置上限 # 圆形度过滤:降低阈值或暂时关闭 pp.filterByCircularity = True pp.minCircularity = 0.5 # 放宽圆形度要求 # 凸性过滤:可暂时关闭以调试,后续再调整 pp.filterByConvexity = False # pp.minConvexity = 0.2 # 惯性比过滤:可暂时关闭以调试 pp.filterByInertia = False # pp.minInertiaRatio = 0.1 detector = cv2.SimpleBlobDetector_create(pp) keypoints = detector.detect(dustImage) numberOfBlobs = len(keypoints) if numberOfBlobs > 0: print(f"{numberOfBlobs} blobs detected!") # 直接在原图上绘制关键点,无需创建空白图 blobs = cv2.drawKeypoints(dustImage, keypoints, None, (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) text = f"Number of Blobs: {len(keypoints)}" # 调整文本位置适配测试图尺寸(测试图是512x512,所以把y设为480) cv2.putText(blobs, text, (20, 480), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 100, 255), 2) cv2.namedWindow('img', cv2.WINDOW_NORMAL) cv2.resizeWindow("img", 900, 900) cv2.imshow("img", blobs) cv2.waitKey(0) cv2.destroyAllWindows() else: print('No blobs detected') return numberOfBlobs if __name__ == '__main__': img0 = plt.imread('artificial.png') # 检查图像通道数,如果是RGB则转灰度 if len(img0.shape) == 3: img0 = cv2.cvtColor(img0, cv2.COLOR_RGB2GRAY) img1 = normalizeImage(img0) # 此时img1已经是单通道灰度图,无需再次转换 detectBlobs(img1)
调试建议
- 逐步开启过滤项:先关闭所有过滤(除了面积和blobColor),确保能检测到Blob后,再逐步开启圆形度、凸性、惯性比等过滤项,调整阈值至符合你的需求。
- 确认图像输入:在
detectBlobs函数开头添加cv2.imshow("input", dustImage); cv2.waitKey(0),确认输入到检测器的图像是黑底白Blob的正确灰度图。 - 适配原任务:当测试图检测成功后,再将参数迁移到复杂灰度图的浅色污点检测,可适当调整面积阈值和blobColor(如果污点是浅色,blobColor设为255;如果是比背景深的浅色,可调整阈值或先做二值化)。
内容的提问来源于stack exchange,提问作者İpek
相关产品推荐
相关产品推荐

