Это решение будет работать для двух изображений, которые вы предоставили. Это также должно быть хорошим решением для всех других изображений, которые имеют аналогичную окраску и форму «v» (или, по крайней мере, частичную форму «v»), указывающую вправо.
Давайте сначала посмотрим на более простое изображение. Я начал с сегментации изображения с использованием цветовых пространств.
# Convert frame to hsv color space
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# Define range of pink color in HSV
(b,r,g,b1,r1,g1) = 0,0,0,110,255,255
lower = np.array([b,r,g])
upper = np.array([b1,r1,g1])
# Threshold the HSV image to get only pink colors
mask = cv2.inRange(hsv, lower, upper)
![цветовые пространства](https://i.stack.imgur.com/kuy3i.png)
Затем я нашел mid_point
, где было равное количество белого выше и ниже этой строки.
# Calculate the 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)
![затопленный](https://i.stack.imgur.com/DMuU0.png)
Теперь, когда у меня есть заполненное изображение, я знаю, что точка, которую я ищу, — это серый пиксель, ближайший к правой стороне изображения.
# Find the gray pixel that is furthest to the right
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 no gray pixel is found, break out of the loop
if not found: break
idx += 1
Результат:
а>
Теперь более сложное изображение. На изображении справа буква «v» не полностью соединяется:
![не подключается](https://i.stack.imgur.com/SUZ5e.png)
Чтобы закрыть «v», я итеративно расширил маску, проверяя, связана ли она:
# Flood fill and dilate loop
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
# Break out of the loop of the right side of the image is black
if mask_temp[h-1,w-1]==0 and mask_temp[1, w-1]==0: break
а>
Это результат:
а>
person
Stephen Meschke
schedule
20.05.2019