Я следил за изображением:
Я хочу извлечь из него только строки — только строки без текста.
Как лучше всего это сделать?
Я попробовал использовать библиотеку Python cv2 и HoughLinesP, следуя коду:
img = cv2.imread('/Users/tekija/Documents/image.png')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_thr = cv2.threshold(img_gray, 120, 255, cv2.THRESH_BINARY)
lines = cv2.HoughLinesP(
img_thr, rho=1, theta=np.pi / 180, threshold=128, minLineLength=600, maxLineGap=30)
lines = lines.squeeze()
но результаты:
Всегда ли линии цветные, а не черные? Если это так, вы можете использовать насыщенность из HSV, чтобы найти их обычно.
Альтернативно, получите контуры и отфильтруйте по длине, чтобы исключить короткие из символов.
Было ли это полезно: Хороший подход к обнаружению линий на изображении?
@DaSt да, линии всегда одного цвета. Иное, чем текст полигонов.
@ fmw42 Да, линии всегда окрашены, но цвет не уникален для каждого изображения.
@user2727167 user2727167 Итак, попробуйте преобразовать в HSV и посмотреть канал насыщения. У вас должна быть возможность установить порог для извлечения только строк. Возможно, вам придется заняться морфологией, чтобы удалить небольшие пятна, оставшиеся от текста, или получить контуры и выбросить небольшие фрагменты.
это в контексте приложения ГИС, не так ли? тот, кто предоставит эти изображения, также может предоставить вам исходные данные ГИС.
Я лишь немного изменил ваш код. Добавлена инверсия и изменены параметры.
import cv2
import numpy as np
img = cv2.imread('lines.png')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_thr = cv2.threshold(img_gray, 120, 255, cv2.THRESH_BINARY_INV)[1]
lines = cv2.HoughLinesP(img_thr, rho=1, theta=np.pi / 180/30, threshold=60, minLineLength=150, maxLineGap=4)
lines = lines.squeeze()
for i in range(lines.shape[0]):
cv2.line(img, (lines[i,0], lines[i,1]), (lines[i,2], lines[i,3]), (255,0,0),2)
cv2.imwrite('lines_out.png', img)
Мне нравится ваше улучшение, но в правом нижнем углу изображения не хватает части.
Попробуйте исправить параметр minLineLength.
Поскольку вы подтвердили, что линии всегда имеют один и тот же цвет, имеет смысл сначала отфильтровать по этому цвету, а затем обнаружить линии.
import cv2
import numpy as np
# Load image
image = cv2.imread('demo.png')
# Convert to HSV
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
# Define color range (original is #7e3553)
lower_range = np.array([155, 100, 20])
upper_range = np.array([175, 255, 255])
# Create mask
mask = cv2.inRange(hsv_image, lower_range, upper_range)
# Dilate the mask to fill in small gaps
mask = cv2.dilate(mask, (3,3), iterations=2)
# Detect points that form a line
lines = cv2.HoughLinesP(mask, 1, np.pi/180, 100, minLineLength=10, maxLineGap=250)
# Draw lines on new mask
line_mask = np.zeros(image.shape[:2], dtype=np.uint8)
for line in lines:
x1, y1, x2, y2 = line[0]
cv2.line(line_mask, (x1, y1), (x2, y2), 255, 3)
# Erode to thin the lines
line_mask = cv2.erode(line_mask, (3,3), iterations=2)
cv2.imwrite('demo_output.png', line_mask)
Вот результат, обратите внимание, как закрылись все пробелы вверху и внизу справа:
Всегда ли линии одного и того же цвета?