【问题标题】:Watershed segmentation on spherical reflecting objects球面反射物体的分水岭分割
【发布时间】: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)

标签:https://i.stack.imgur.com/M6hZb.png

【问题讨论】:

  • 您可能希望显示单个标签而不是封闭圆圈,以更深入地了解分水岭分割对您的图像的效果。您还可以尝试反转图像颜色或调整阈值。
  • @fdermishin 我只是尝试显示标签,这真的很糟糕。我会更新这个问题。我玩的门槛,无法提高任何东西。与 HSV 一起工作也是如此。但我可能做错了。仅供参考,我测试了 cellpose(我也在问题中添加了一个注释)并且它有效。但我不想使用深度学习。
  • 是的,这是非常错误的方法。看看thresh,不是距离变换分水岭有用的图片类型。
  • 如果您对图像采集有影响,您可以做很多事情来使这更容易:将照明更改为更加漫射,使用与球的颜色不同的背景颜色和照明,使用透射光成像等。
  • 鉴于那张图片,我只需选择一个球作为模板并运行 matchTemplate。它们看起来都一样,反射方面。不过,这确实需要您选择一个球作为模板。如果我必须将其作为工业光学检测任务,我肯定会修复场景、照明、采集

标签: python opencv computer-vision image-segmentation scikit-image


【解决方案1】:

matchTemplate“解决方案”与opencv/samples/mouse_and_match.py

使用任何你喜欢的东西来找到峰值。

是的,使用这种方法,您必须手动选择模板。

为了解决这个问题,可能会有一些利用自相似性(自相关)的方法。给读者练习。

您不能选择整个球,因为它们的大小各不相同,所以这已经是模板匹配的一个巨大缺点,而且围绕圆形的矩形包含大量非对象像素,这会降低相关性得分部分不同。

选择反射是有效的(从中等球上),因为反射显示了一个具有强烈对比度的环境。

注意到顶部附近的一个小球,稍微向右?由于很多原因,它做得不太好。

【讨论】:

  • 那个球匹配得很好——它在右手图像上有一个亮点。您可能误读了位置
  • 此外,您的位置不会是质心,除非您将参考图像相对于球居中。也许你做到了。不过,我喜欢你所做的。
  • 据我了解,我可以在任何形状上使用圆形补丁并以不同方式缩放图像(我的尺寸非常有限)。像这样pyimagesearch.com/2015/01/26/…
  • 当然要调整坐标。它们相对于模板的左上角,因此它们是与模板匹配的矩形的原点。矩形的中心不必是您选择的中心。这是一个小细节。还有右边顶部的那个弱球,我没有说它不在响应图中,而是说它很弱。
  • @Y0da 是的,正确,您可以对其进行多重缩放以捕捉不同的大小。只是增加了一些处理时间。鉴于这已经在很短的时间内运行,我认为这是个好主意。
猜你喜欢
  • 2012-07-11
  • 2019-06-06
  • 1970-01-01
  • 2019-08-06
  • 2018-10-26
  • 1970-01-01
  • 1970-01-01
  • 2011-09-08
  • 2020-06-14
相关资源
最近更新 更多