#python #opencv #image-processing #euclidean-distance #canny-operator
#python #opencv #обработка изображений #евклидово расстояние #canny-оператор
Вопрос:
У меня есть черная линия и фиолетовые линии. Я хочу рассчитать расстояние между каждой фиолетовой точкой пикселя на аккуратном изображении и ближайшей черной линией наиболее эффективным и быстрым способом. Как я могу это сделать? Есть ли какая-либо функция opencv-python?
Комментарии:
1. Вы имеете в виду, что хотите знать для каждого отдельного фиолетового пикселя расстояние до ближайшего черного пикселя?
2. Да, вы все правильно поняли. Я сделаю это на изображении canny.
Ответ №1:
Я думаю, что это близко, но еще не проверял это слишком много:
#!/usr/bin/env python3
import cv2
import numpy as np
# Load input image
im = cv2.imread('PBv6H.png')
# DEBUG Get list of all unique colours in image
# np.unique(im.reshape((-1,3)),axis=0)
# Find purple pixels
purplepixels = np.where(np.all(im==[164,73,163],axis=-1))
# Make black and white image with only the black pixels from original
bw = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
_, bw = cv2.threshold(bw,1,255,cv2.THRESH_BINARY)
# DEBUG cv2.imwrite('bw.png', bw)
# Now calculate the distance from every pixel to the nearest black one
# Every pixel in "dst" image has a brightness equal to its distance to nearest black pixel
dst = cv2.distanceTransform(bw, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
# Print out the distance to the nearest black pixel for each purple pixel
for y,x in zip(purplepixels[0], purplepixels[1]):
print(f'[{y},{x}]: {dst[y,x]}')
Это изображение с преобразованием расстояния — чем ярче пиксель, тем дальше он находится от черного пикселя:
Вот черно-белое изображение с пороговым значением:
Ключевые слова: OpenCV, обработка изображений, преобразование расстояния, distancetransform, cv2.distancetransform, Python.
Комментарии:
1. Большое вам спасибо. Вы сделали меня очень счастливым. Я ценю это. Интересно, сможем ли мы узнать координату ближайшего черного пикселя?
2. Вы должны быть в состоянии перейти
cv2.distanceTransform()
наdst, labels = cv2.distanceTransformWithLabels(bw, cv2.DIST_L2, cv2.DIST_MASK_PRECISE, labelType=cv2.DIST_LABEL_PIXEL)
3. Собственно, именно по этой причине я попросил вас уточнить в комментариях, что вам просто нужно расстояние (а не координаты ближайшего пикселя). Если вам действительно нужны координаты ближайшего пикселя, возможно, вам лучше использовать функцию SciPy
scipy.ndimage.morphology.distance_transform_edt()
4. Я пишу эту функцию и решаю ее. Большое вам спасибо.
edt, inds = ndimage.distance_transform_edt(bw, return_indices=True)
Ответ №2:
Рассмотрим «преобразование расстояния» на изображении одного из типов линий. Затем для любой точки другого типа линии мгновенно найдите расстояние.
Или превратите ваши линии в полигоны / полилинии. Это огромное сокращение объема данных и превращает вашу проблему в проблему геометрии.
Комментарии:
1. Да, я так думаю, но извините, я новичок в обработке изображений, поэтому мне нужна дополнительная информация или пример, чтобы сделать это.
2. пожалуйста, найдите «преобразование расстояния opencv». вы найдете небольшое руководство по этому вопросу в официальной документации.