这个解决方案适用于您提供的两张图片。对于所有具有类似颜色和指向右侧的“v”形状(或至少部分“v”形状)的其他图像,这也应该是一个很好的解决方案。
首先让我们看一下更简单的图像。我通过使用颜色空间对图像进行了分割。
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
(b,r,g,b1,r1,g1) = 0,0,0,110,255,255
lower = np.array([b,r,g])
upper = np.array([b1,r1,g1])
mask = cv2.inRange(hsv, lower, upper)
![color spaces](https://istack.dev59.com/kuy3i.webp)
接下来,我找到了
mid_point
,即在该行上方和下方都有相等数量的白色像素。
mid_point = 1
top, bottom = 0, 1
while top < bottom:
top = sum(sum(mask[:mid_point, :]))
bottom = sum(sum(mask[mid_point:, :]))
mid_point += 1
然后,我从中点开始填充图像:
bg = np.zeros((h+2, w+2), np.uint8)
kernel = np.ones((k_size, k_size),np.uint8)
cv2.floodFill(mask, bg, (0, mid_point), 123)
![floodfilled](https://istack.dev59.com/DMuU0.webp)
现在我有了洪水填充图像,我知道我要找的点是最靠近图像右侧的灰色像素。
idx = 0
while True:
column = mask_temp[:,idx:idx+1]
element_id, gray_px, found = 0, [], False
for element in column:
if element == 123:
v_point = idx, element_id
found = True
element_id += 1
if not found: break
idx += 1
结果:
![result1](https://istack.dev59.com/FbEYL.webp)
现在是较难的图像。 在右侧的图像中,“v”未完全连接:
![does not connect](https://istack.dev59.com/SUZ5e.webp)
为了关闭 'v' 字形,我迭代地膨胀掩码并检查它是否连接:
k_size, iters = 1, 1
while True:
bg = np.zeros((h+2, w+2), np.uint8)
mask_temp = mask.copy()
kernel = np.ones((k_size, k_size),np.uint8)
mask_temp = cv2.dilate(mask_temp,kernel,iterations = iters)
cv2.floodFill(mask_temp, bg, (0, mid_point), 123)
cv2.imshow('mask', mask_temp)
cv2.waitKey()
k_size += 1
iters += 1
if mask_temp[h-1,w-1]==0 and mask_temp[1, w-1]==0: break
![dilation](https://istack.dev59.com/ktBS3.gif)
这是最终的输出:
![output2](https://istack.dev59.com/Wzges.webp)