#python-3.x #opencv #image-processing
#python-3.x #opencv #обработка изображений
Вопрос:
Я обрабатываю большую часть изображений, похожих на приведенное ниже. Я хотел бы иметь возможность вычислить среднюю ширину черной линии (примерно желтую линию на изображении), но не уверен, как лучше всего выполнить это в python. Сама желтая линия отсутствует на изображениях, только черные полосы.
Исходное изображение:
Комментарии:
1. Как определяется темная полоса? Это не кажется самой темной частью изображения. Это всегда прямо над правой полосой? Всегда ли это темная полоса определенного диапазона ширины? Обнаружение полосы составляет 99% проблемы, после обнаружения легко получить ширину. Итак, нам нужно знать логику, которую нужно использовать для идентификации полосы.
2. Темная полоса сама по себе является «полосой износа» на сверле. Таким образом, ширина полосы довольно динамична в зависимости от уровня использования сверла. Темная полоса всегда находится над белой полосой. Вы правы, что обычно это не самая темная часть изображения.
Ответ №1:
Первый подход заключается в использовании line-detector
.
-
Найдите края вашего изображения
-
Обнаружение линий
-
lines = createFastLineDetector(_length_threshold=20).detect(canny_img)
-
-
Вычислите расстояние
-
for cur in lines: (x1, y1, x2, y2) = cur[0] dist = math.sqrt(((x2 - x1) ** 2) ((y2 - y1) ** 2)) print("Distance between ({:.2f}, {:.2f}) - ({:.2f}, {:.2f}) = {:.2f}" .format(x1, y1, x2, y2, dist)) cv2.line(img, pt1=(x1, y1), pt2=(x2, y2), color=(0, 255, 0), thickness=2) cv2.imshow("detected", img) cv2.waitKey(0)
-
-
Результат
Обновить
Если мы применим image-segmentation
то, что у нас есть, к следующей области:
- Мы хотим найти длину красных линий и найти расстояние между красными линиями, используя формулу.
Верхняя:
Distance between (118.06, 868.42) - (96.92, 871.40)
Distance between (95.94, 872.67) - (75.85, 876.11)
Distance between (74.88, 877.33) - (24.85, 886.16)
Distance between (23.96, 887.62) - (0.01, 890.06)
Чем ниже:
Distance between (79.07, 894.60) - (99.02, 892.15)
Distance between (104.01, 886.54) - (125.99, 887.20)
Distance between (40.93, 901.45) - (66.05, 898.40)
Distance between (0.00, 906.02) - (33.99, 905.52)
Если вы случайным образом выберете две точки: (66.05, 898.40)
и (24.85 - 886.16)
, расстояние будет: 41.23
Решение не идеально, но оно может дать подсказку для лучшей идеи. Поэтому я публикую в качестве ответа.
Код:
import cv2
import math
import numpy as np
from cv2.ximgproc import createFastLineDetector
img = cv2.imread('calculate_width.png')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray_img, 150, 255,
cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)
kernel = np.ones((5, 5), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
sure_bg = cv2.dilate(opening, kernel)
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
_, sure_fg = cv2.threshold(dist_transform, 0.3*dist_transform.max(),
255, 0)
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)
lines = createFastLineDetector(_length_threshold=20).detect(unknown)
for cur in lines:
(x1, y1, x2, y2) = cur[0]
dist = math.sqrt(((x2 - x1) ** 2) ((y2 - y1) ** 2))
print("Distance between ({:.2f}, {:.2f}) - ({:.2f}, {:.2f})"
.format(x1, y1, x2, y2))
cv2.line(img, pt1=(x1, y1), pt2=(x2, y2), color=(0, 255, 0),
thickness=2)
cv2.imshow("detected", img)
cv2.waitKey(0)
Комментарии:
1. Спасибо за ответ @Ahx. Желтая линия в OP была просто для обозначения черной линии, которую я пытаюсь вычислить среднее расстояние, и отсутствует на реальных изображениях, которые я обрабатываю. Исходя из вашего ответа, похоже, что желтая линия должна присутствовать, поскольку для вычислений? Я обновлю OP, чтобы сделать это более понятным.
2. Я думал, что желтая линия доступна. Итак, у вас есть изображение шаблона?
3. Просто добавил его в OP @Ahx. Извините за путаницу!
4. Нет, никаких проблем.
5. Приносим извинения за позднее продолжение. С некоторыми небольшими изменениями это сработало для моего варианта использования, спасибо!