#python #opencv
#питон #opencv
Вопрос:
На самом деле я хочу удалить расческу под датами с помощью opencv. Прикрепление изображения для справки .До сих пор я могу удалить горизонтальную линию гребня с помощью кода, приведенного ниже.`
import cv2 import os image = cv2.imread(r'path to file') gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)[1] horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25,1)) detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2) cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] for c in cnts: cv2.drawContours(image, [c], -1, (255,255,255), 2) repair_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,6)) ver =cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, repair_kernel, iterations=1) result = 255 - cv2.morphologyEx(255 - image, cv2.MORPH_CLOSE, repair_kernel, iterations=1) cv2.imshow('image', image) cv2.imshow('result', result) cv2.imwrite(r"path to image",image) cv2.waitKey()`
Комментарии:
1. Я бы вручную определил положение всех линий и поместил прямоугольники while в эти места — используя обычные функции. Или вручную измерил бы расстояние между линиями, а затем мне пришлось бы найти (даже вручную) первую строку, а затем я мог бы рассчитать позиции для других строк.
2. Или я бы нашел все контуры и удалил контуры, которые имеют ту же высоту, что и линии на экране. ИЛИ удалите все контуры, высота которых намного меньше, чем у других контуров.
3. ИЛИ проверьте, какие контуры имеют одинаковое ВЕРХНЕЕ и НИЖНЕЕ положение (чтобы они имели одинаковую высоту).
4. Спасибо за ответ , на самом деле я новичок в opencv, можете ли вы предоставить фрагмент кода, это было бы весьма полезно
Ответ №1:
Вертикальные линии, вероятно, являются самыми маленькими контурами (с наименьшей высотой), поэтому я использую его для их обнаружения.
Снова использую findContours
, но cv2.RETR_LIST
вместо cv2.RETR_EXTERNAL
этого я получаю все контуры.
Для каждого контура я вычисляю height = max(Y) - min(Y)
Если height
между 23 и 25, то у меня есть вертикальный прямоугольник, который я могу удалить, используя заполненный drawContours
Мне пришлось проверить between 23 and 25
, потому что я нашел 2 контура меньшего размера, которые мне пришлось пропустить. Потому что мне пришлось выбирать значения 23, 25 вручную, поэтому этот метод не настолько универсален.
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) cnts = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] for c in cnts: #X = c[:,0,0] Y = c[:,0,1] min_y = min(Y) max_y = max(Y) height = max_y - min_y if 23 lt;= height lt;= 25: print(f'{max_y:3} - {min_y:3} = {height} lt;---') cv2.drawContours(image, [c], -1, (0,0,255), 2) # red border cv2.drawContours(result, [c], -1, (255,255,255), -1) # filled else: print(f'{max_y:3} - {min_y:3} = {height}') print('----')
Изображение:
Результат:
Полный код:
import cv2 import os image = cv2.imread('Cfxvo.png') gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)[1] horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25,1)) detected_lines = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2) cnts = cv2.findContours(detected_lines, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] for c in cnts: cv2.drawContours(image, [c], -1, (255,255,255), 2) repair_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,6)) ver = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, repair_kernel, iterations=1) result = 255 - cv2.morphologyEx(255 - image, cv2.MORPH_CLOSE, repair_kernel, iterations=1) # --- new code --- gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) cnts = cv2.findContours(gray, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] for c in cnts: X = c[:,0,0] Y = c[:,0,1] min_y = min(Y) max_y = max(Y) height = max_y - min_y if 23 lt;= height lt;= 25: print(f'{max_y:3} - {min_y:3} = {height} lt;---') cv2.drawContours(image, [c], -1, (0,0,255), 2) cv2.drawContours(result, [c], -1, (255,255,255), -1) else: print(f'{max_y:3} - {min_y:3} = {height}') print('----') # --- cv2.imshow('image', image) cv2.imshow('result', result) cv2.imwrite("output-image.png", image) cv2.imwrite("output-result.png", result) cv2.waitKey(0) cv2.destroyAllWindows()
Редактировать:
Вы также можете проверить другие значения, чтобы убедиться в этом.
Все прямоугольники имеют одинаковые width
6-7 пикселей.
И у всех есть max_y = 61