углы краев не острые с фильтром Canny

Я пытаюсь обнаружить края изображения с помощью фильтра Canny. Мне удалось обнаружить изображения, но углы не очень острые (выделены красными кругами). Удивительно, но первый угол острый и не выгорел по сравнению с другими углами. Почему это происходит и как этого избежать??

Пожалуйста, взгляните на прикрепленное изображение.введите здесь описание изображения

Мой код:

ребра = cv2.Canny(изображение,0,255)

Я не применял никакого размытия, так как это делает углы хуже. Более того, изменение мин и макс значений для Canny также не имеет никакого значения.


person user1388142    schedule 27.01.2016    source источник


Ответы (2)


Алгоритм Канни включает сглаживание по Гауссу, что немного повлияет на градиент в ваших углах. https://en.wikipedia.org/wiki/Canny_edge_detector

Если вы знаете, что все ваши изображения будут изображениями без шума, такими как образец, который вы предоставили, вам следует подумать о том, чтобы взять лапласиан изображения.

person Matthew Pope    schedule 27.01.2016
comment
даже с лапласианом углы кромки не острые - person user1388142; 27.01.2016
comment
Края на изображении, если вы увеличите масштаб, будут не резкими, а скорее градиентными. Если ваши края имеют ширину в несколько пикселей, то, насколько я знаю, нет никакой гарантии, что вы получите идеально четкие углы. Вы можете сделать изображение черно-белым, чтобы избавиться от плавных краев. - person Matthew Pope; 27.01.2016

Помимо применения размытия, как уже упоминалось, алгоритм Кэнни предназначен для утончения края. Начав с бинарного образа, вы не действуете в рамках предположений, на которых построен Canny.

Если известно, что ваши изображения являются двоичными, вы можете найти искомое преимущество по искажает изображение, а затем вычитает его из оригинала. Помимо предоставления вам ожидаемого результата, это также может быть быстрее.

С++ используется для создания изображения:

auto image = cv::imread("binary.png", -1);
cv::Mat eroded_image, edge_image;

cv::erode(image, eroded_image, cv::Mat());

edge_image = image - eroded_image;

Или python, как описано на учебной странице OpenCV. (размер ядра отредактирован):

kernel = numpy.ones((3,3), numpyp.uint8)
eroded_image = cv2.erode(image, kernel)

Исходное изображение введите здесь описание изображения

Вы также можете использовать морфологический градиент, описанный в том же уроке, который в основном представляет собой ту же операцию, но вычитание из расширенного изображения вместо исходного. Это обеспечит более толстый край, но его можно считать более «правильным», поскольку он сосредоточен вокруг увеличения интенсивности.

person buckminst    schedule 17.08.2018