Вытеснение отдельных персонажей в изображении - PullRequest
0 голосов
/ 08 января 2019

Я пытаюсь отключить функцию анти-бота в программе, где пользователь должен нажимать на буквы на изображении в буквенно-цифровом порядке. Мне удалось несколько извлечь текст из фона, используя предварительную обработку, но мне все еще нужно выровнять каждый отдельный символ, чтобы получить оптимальные результаты с помощью Tesseract.

Изображение перед использованием Hough Lines, просто предварительная обработка enter image description here

Исходные изображения с линиями, обнаруженными HoughLinesP, нарисованы enter image description here Я пытался использовать Canny Edge Detector + Hough Lines, чтобы найти строку под каждым символом. Однако он считается непоследовательным и слишком зависит от качества строки, и я не могу различить нижнюю строку и строки, обнаруженные на самих символах.

Вот код, который я пробовал:

# -*- coding:utf-8 -*-
import cv2, numpy as np, time
img_roi = [48, 191, 980, 656]  # x1, y1, x2, y2
src_img_dir = "images/source/9.png"
bg_img = cv2.imread("images/background.png", cv2.IMREAD_COLOR)[img_roi[1]:img_roi[3], img_roi[0]:img_roi[2]]
# The background of the area is constant. So I have used a reference background image and removed pixels which have a similar H value as the background

bg_hsv = cv2.cvtColor(bg_img, cv2.COLOR_BGR2HSV)
src_img = cv2.imread(src_img_dir, cv2.IMREAD_COLOR)[img_roi[1]:img_roi[3], img_roi[0]:img_roi[2]]
# This image is the image where letters are placed on top of the background image

src_hsv = cv2.cvtColor(src_img, cv2.COLOR_BGR2HSV)
mask = np.zeros([src_img.shape[0], src_img.shape[1], 3], dtype=np.uint8)

offset = 3
start_time = time.time()
for y in range(src_img.shape[0]):
    for x in range(src_img.shape[1]):
        sp = src_hsv[y][x]
        bp = bg_hsv[y][x]

        if bp[0]-offset <= sp[0] <= bp[0]+offset:
            if sp[1] >= 109:
                mask[y][x] = src_img[y][x]
        elif sp[1] <= 90:
            if sp[0] >= 67:
                mask[y][x] = src_img[y][x]
            elif sp[2] >= 125 and sp[1] >= 20:
                mask[y][x] = src_img[y][x]
        else:
            mask[y][x] = src_img[y][x]
        """if sp[1] >= 60 and sp[2] >= 60:
            mask[y][x] = src_img[y][x]
            #mask[y][x] = conv"""

print("duration", time.time()-start_time)
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2HSV)
#mask[:,:,2] = 255
mask = cv2.cvtColor(mask, cv2.COLOR_HSV2BGR)
mask_gray = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(mask_gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
opened = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, (3,3))
opened = cv2.morphologyEx(opened, cv2.MORPH_OPEN, (3,3))
opened = cv2.erode(opened, (3,3))
opened = cv2.dilate(opened, (3,3))
opened = cv2.dilate(opened, (5, 5))
opened = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, (3,3))
opened = cv2.erode(opened, (3,3))
opened = cv2.erode(opened, (3,3))
final_img = opened
#edges = cv2.Canny(final_img, 0, 255)
lines = cv2.HoughLinesP(final_img, 1, np.pi / 180, 20, minLineLength=10, maxLineGap=3)
for line in lines:
        coords = line[0]
        cv2.line(src_img, (coords[0], coords[1]), (coords[2], coords[3]), [255,255,255], 2)
#cv2.imshow("can", edges)


#cv2.drawContours(src_img, fixed_contours, -1, (0,255,0), 2)
cv2.imshow("src", src_img)
cv2.imshow("", final_img)

cv2.waitKey(0)
cv2.destroyAllWindows()

1 Ответ

0 голосов
/ 08 января 2019

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

Я бы сделал многоэтапный подход к вашему отфильтрованному изображению (уже неплохо)

  • сначала обнаруживает интересующие области, которые содержат два значительно больших объекта (буква / цифра + подчеркивание), отфильтровывая пиксели шума
  • затем определите подчеркивание как длинное и плоское из двух (буква «I» и цифра «1» могут быть проблематичными в этом отношении)
  • использовать ориентацию подчеркивания по отношению к локальной области интереса (подчеркивание + символ), чтобы определить, какая сторона находится внизу
  • определяет угол перекоса эвристически: при условии x градусов (петля в узком диапазоне x), сколько сигнала локальной области интереса находится внутри четырехугольника над подчеркиванием, так что угол между основанием (подчеркивание) и левым равен x.
  • использовать функцию разворачивания изображения, чтобы подчеркивание отображалось на нижнем крае прямоугольника с соответствующим отношением ширины к высоте
  • выгода
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...