Как удалить гребень, присутствующий под датами, с изображений с помощью opencv

#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