【发布时间】:2020-12-08 18:07:43
【问题描述】:
我正在尝试使用分水岭进行一些图像分割,以检测图像中的所有球。我遵循了 pyimage tuto。但我得到的结果很差。我的猜测是反射是问题所在。图像仍然很干净,实例看起来很分离。
我在这里使用正确的方法吗?我错过了什么吗? 我测试了cellpose,我得到了几乎完美的结果。当然,这不是相同的方法,我希望通过“经典”计算机视觉技术获得一些东西。
以下是我拥有的代码、原始图像和当前结果。我试图更改参数,但我不确定我在这里做什么。我也看了inRange,但恐怕这些球从来都不是同一种颜色。
原图:https://i.stack.imgur.com/7595R.jpg
import numpy as np
from scipy import ndimage
import cv2
from skimage.feature import peak_local_max
from skimage.segmentation import watershed
import imutils
from matplotlib import pyplot as plt
img = cv2.imread('balls.jpg')
gray = - cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
plt.imshow(gray)
# Things I tried...
# gray = cv2.dilate(gray,kernel,iterations = 1)
# hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# h, s, v = cv2.split(hsv)
thresh = cv2.threshold(gray, 250, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
# compute the exact Euclidean distance from every binary
# pixel to the nearest zero pixel, then find peaks in this
# distance map
D = ndimage.distance_transform_edt(thresh)
localMax = peak_local_max(D, indices=False, min_distance=30, labels=thresh)
# perform a connected component analysis on the local peaks,
# using 8-connectivity, then appy the Watershed algorithm
markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]
labels = watershed(-D, markers, mask=thresh)
# draw on mask
for label in np.unique(labels):
# if the label is zero -> 'background'
if label == 0:
continue
mask = np.zeros(gray.shape, dtype="uint8")
mask[labels == label] = 255
# detect contours in the mask and grab the largest one
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key=cv2.contourArea)
# draw a circle enclosing the object
((x, y), r) = cv2.minEnclosingCircle(c)
cv2.circle(img, (int(x), int(y)), int(r), (0, 255, 0), 2)
cv2.putText(img, "#{}".format(label), (int(x) - 10, int(y)),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)
plt.imshow(img)
【问题讨论】:
-
您可能希望显示单个标签而不是封闭圆圈,以更深入地了解分水岭分割对您的图像的效果。您还可以尝试反转图像颜色或调整阈值。
-
@fdermishin 我只是尝试显示标签,这真的很糟糕。我会更新这个问题。我玩的门槛,无法提高任何东西。与 HSV 一起工作也是如此。但我可能做错了。仅供参考,我测试了 cellpose(我也在问题中添加了一个注释)并且它有效。但我不想使用深度学习。
-
是的,这是非常错误的方法。看看
thresh,不是距离变换分水岭有用的图片类型。 -
如果您对图像采集有影响,您可以做很多事情来使这更容易:将照明更改为更加漫射,使用与球的颜色不同的背景颜色和照明,使用透射光成像等。
-
鉴于那张图片,我只需选择一个球作为模板并运行 matchTemplate。它们看起来都一样,反射方面。不过,这确实需要您选择一个球作为模板。如果我必须将其作为工业光学检测任务,我肯定会修复场景、照明、采集
标签: python opencv computer-vision image-segmentation scikit-image