Как вычислить евклидово расстояние в аккуратном изображении

#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». вы найдете небольшое руководство по этому вопросу в официальной документации.