如何检测模糊的斑点?

4
我希望能在这张图片中检测出所有的亮点 (https://i.imgur.com/UnTWWHz.png),我尝试过二值化的方法,但是只能检测出最明亮的那些。正如您在下面的图片中所看到的。 enter image description here 但是有些斑点没有对焦,我也需要检测它们。你能建议一种方法吗?下图显示了我想在黄圈中检测出的模糊斑点。 enter image description here 我已经用了下面的代码:
import os
import cv2
import numpy as np


path="C:/Slides/Fluoroscent/E_03_G_O_subpics"
imgname="sub_2_4.png"
image = cv2.imread(os.path.join(path,imgname))

#  constants
BINARY_THRESHOLD = 10
CONNECTIVITY = 4
DRAW_CIRCLE_RADIUS = 18
thr=50
#  convert to gray
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

#  threshold the black/ non-black areas
_, thresh = cv2.threshold(gray_image, BINARY_THRESHOLD, thr, cv2.THRESH_BINARY)

#  find connected components
components = cv2.connectedComponentsWithStats(thresh, CONNECTIVITY, cv2.CV_32S)

#  draw circles around center of components
#see connectedComponentsWithStats function for attributes of components variable
centers = components[3]
for center in centers:
    cv2.circle(image, (int(center[0]), int(center[1])), DRAW_CIRCLE_RADIUS, (0,0,255), thickness=1)

cv2.imwrite(os.path.join(path,"result_thresh_"+str(thr)+".png"), image)
cv2.imshow("result", image)
cv2.waitKey(0)

我不能说我理解黄色圈出来的那些和完全没有圈出来的那些有什么不同。 - Itay
2
使用更小的阈值?还是会达到噪声呢? - Micka
1
您可以使用较小的阈值,并使用连通组件或形态学来过滤掉太小的区域。 - fmw42
@Italy 我只是举了一些例子来圈出模糊的图片。但我想要检测出所有的模糊图片。 - Maryam Sadeghi
@Micka 我尝试改变阈值,但没有任何效果。 - Maryam Sadeghi
从猜测来看,15-30的阈值可能适用于更多的斑点。如果您可以使用颜色信息,这也可能是不错的选择。 - Micka
1个回答

3

正如评论中所提到的,通过更改阈值值可以获得更好的结果。我将值分别更改为20和255,并添加了侵蚀以消除一些噪音。您可以尝试使用形态学转换来获得精确的所需结果。在这里阅读更多。

代码:

import cv2
import numpy as np

kernel = np.ones((5,5),np.uint8)
CONNECTIVITY = 4
DRAW_CIRCLE_RADIUS = 18
img = cv2.imread('blobs.png')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(gray_img, 20, 255, cv2.THRESH_BINARY)
erosion = cv2.erode(thresh,kernel,iterations = 1)

components = cv2.connectedComponentsWithStats(erosion, CONNECTIVITY, cv2.CV_32S)

centers = components[3]
for center in centers:
    cv2.circle(img, (int(center[0]), int(center[1])), DRAW_CIRCLE_RADIUS, (0,0,255), thickness=1)

cv2.imshow('Original', img)
cv2.imshow('Thresh', thresh)
cv2.imshow('Erosion', erosion)
cv2.waitKey(0)

结果:

阈值 阈值

腐蚀 腐蚀

带圆的原始图像

圆


这非常有帮助。谢谢!我首先使用颜色过滤器创建了一个二进制掩模来检测绿色区域,然后使用斑点检测来检测它们。但我还需要将3个连接的斑点检测为3个不同的斑点。是否可以使用connectedComponentsWithStats来实现? - Maryam Sadeghi
@MaryamSadeghi 我认为你无法让connectedComponentsWithStats在我提供的阈值图像中将3个连接的blob检测为3个不同的blob。我建议你在阈值图像上使用形态变换。例如,你可以在腐蚀之前使用膨胀,看看是否能够产生更好的结果。 - Christoffer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接