简单的斑点检测器不检测斑点

gyr*_*yre 2 opencv

我正在尝试使用这里描述的简单 blob 检测器,但是我破解的最简单的代码似乎没有产生任何结果:

img = cv2.imread("detect.png")
detector = cv2.SimpleBlobDetector_create()
keypoints = detector.detect(img)
Run Code Online (Sandbox Code Playgroud)

此代码产生空keypoints数组:

[]
Run Code Online (Sandbox Code Playgroud)

我试图检测其中的斑点的图像是:

在此处输入图片说明

我希望至少检测到 2 个斑点——根据文档simpleblobdetector检测到暗斑点,图像确实包含其中的 2 个。

我知道这可能是我在这里遗漏的非常简单的事情,但我似乎无法弄清楚它是什么。我疯狂的猜测是,它必须对 blob 的圆形度做一些事情,但是尝试各种过滤器参数我似乎无法找出正确的圆形度参数。

更新:根据下面的评论,有人建议我应该反转我的图像,尽管文档建议(除非我误读了它),我已经尝试反转它并再次运行示例:

img = cv2.imread("detect.png")
img = cv2.bitwise_not(img)
detector = cv2.SimpleBlobDetector_create()
keypoints = detector.detect(img)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

然而,正如我怀疑这给出了相同的结果 - 没有检测:

[]
Run Code Online (Sandbox Code Playgroud)

api*_*i55 5

问题是参数:) 而底部的 blob 离边界太近了...

您可以查看此github 链接中的默认参数。此链接末尾有一个有趣的图表,您可以在其中检查不同的参数将如何影响结果。

基本上你可以看到默认情况下它是通过惯性、面积和凸度过滤的。现在,如果您移除凸度和惯性过滤器,它将标记顶部的过滤器。如果您移除区域过滤器,它仍然只会显示顶部的斑点...底部的主要问题是它离边界太近了...而且似乎不是检测器的“斑点”。 .. 但是如果给图像添加一个小边框,它就会出现。这是我用于它的代码:

import cv2
import numpy as np
img = cv2.imread('blob.png');
# create the small border around the image, just bottom
img=cv2.copyMakeBorder(img, top=0, bottom=1, left=0, right=0, borderType= cv2.BORDER_CONSTANT, value=[255,255,255] ) 

# create the params and deactivate the 3 filters
params = cv2.SimpleBlobDetector_Params()
params.filterByArea = False
params.filterByInertia = False
params.filterByConvexity = False

# detect the blobs
detector = cv2.SimpleBlobDetector_create(params)
keypoints = detector.detect(img)

# display them
img_with_keypoints = cv2.drawKeypoints(img, keypoints, outImage=np.array([]), color=(0, 0, 255),flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
cv2.imshow("Frame", img_with_keypoints)
cv2.waitKey(0)
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)

以及由此产生的图像:

在此处输入图片说明

是的,您无需停用过滤器而是更改其参数即可获得类似的结果。例如,这些参数产生完全相同的结果:

params = cv2.SimpleBlobDetector_Params()
params.maxArea = 100000
params.minInertiaRatio = 0.05
params.minConvexity = .60
detector = cv2.SimpleBlobDetector_create(params)
Run Code Online (Sandbox Code Playgroud)

这将在很大程度上取决于手头的任务以及您要检测的内容。然后使用每个过滤器的最小值/最大值。