Улучшить картинку, чтобы обнаружить персонажей внутри области - PullRequest
0 голосов
/ 24 сентября 2018

Моя цель - обнаружить символы на изображениях такого типа.Input Image

Мне нужно улучшить изображение, чтобы Tesseract лучше распознавал его, вероятно, выполнив следующие шаги:

  • Поверните изображение так, чтобысиний прямоугольник горизонтален [Нужна помощь в этом]
  • Обрежьте изображение в соответствии с синим прямоугольником [Нужна помощь в этом]
  • Примените фильтр порогового значения и размытие по Гауссу
  • Используйте Tesseract для обнаружения символов

    img = Image.open('grid.jpg')
    image = np.array(img.convert("RGB"))[:, :, ::-1].copy()
    
    
    # Need to rotate the image here and fill the blanks
    # Need to crop the image here
    
    # Gray  the image
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    # Otsu's thresholding
    ret3, th3 = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    
    # Gaussian Blur
    blur = cv2.GaussianBlur(th3, (5, 5), 0)
    
    # Save the image
    cv2.imwrite("preproccessed.jpg", blur)
    
    # Apply the OCR
    pytesseract.pytesseract.tesseract_cmd = r'C:/Program Files (x86)/Tesseract-OCR/tesseract.exe'
    tessdata_dir_config = r'--tessdata-dir "C:/Program Files (x86)/Tesseract-OCR/tessdata" --psm 6'
    
    preprocessed = Image.open('preproccessed.jpg')
    boxes = pytesseract.image_to_data(preprocessed, config=tessdata_dir_config)
    

Вот полученное изображение, которое не подходит для распознавания: output

Проблемы с распознаванием:

  • Синий прямоугольник иногда распознается как символы, поэтому я хотел бы обрезать изображение
  • Иногда Tesseract распознает символы в строкекак слово (GCVDRTEUQCEBURSIDEEC), а иногда и как отдельные буквы.Мне бы хотелось, чтобы это было всегда слово.
  • Маленькая пирамида в правом нижнем углу распознается как символ

Любые другие предложения по улучшению распознавания приветствуются

Ответы [ 4 ]

0 голосов
/ 25 сентября 2018

Это немного другой подход, использующий pyvips .

Если изображение просто поворачивается (т. Е. Мало или вообще без перспективы), вы можете воспользоваться БПФ, чтобы найти угол поворота.Хорошая регулярная сетка символов создаст четкий набор линий на преобразовании.Это должно быть очень крепким.Это делает БПФ для всего изображения, но вы могли бы сначала немного его уменьшить, если хотите увеличить скорость.

import sys
import pyvips

image = pyvips.Image.new_from_file(sys.argv[1])

# to monochrome, take the fft, wrap the origin to the centre, get magnitude
fft = image.colourspace('b-w').fwfft().wrap().abs()

Создание:

enter image description here

Чтобы найти угол линий, поверните полярные координаты в прямоугольные и найдите горизонтали:

def to_rectangular(image):
    xy = pyvips.Image.xyz(image.width, image.height)
    xy *= [1, 360.0 / image.height]
    index = xy.rect()
    scale = min(image.width, image.height) / float(image.width)
    index *= scale / 2.0
    index += [image.width / 2.0, image.height / 2.0]
    return image.mapim(index)

# sum of columns, sum of rows
cols, rows = to_rectangular(fft).project()

Изготовление:

enter image description here

С проекцией:

enter image description here

Затем просто посмотрите на пик и поверните:

# blur the rows projection a bit, then get the maxpos
v, x, y = rows.gaussblur(10).maxpos()

# and turn to an angle in degrees we should counter-rotate by
angle = 270 - 360 * y / rows.height

image = image.rotate(angle)

enter image description here

Чтобы обрезать, я взял горизонтальный иВертикальные проекции снова, затем поиск пиков с B> G.

cols, rows = image.project() 

h = (cols[2] - cols[1]) > 10000
v = (rows[2] - rows[1]) > 10000

# search in from the edges for the first non-zero value
cols, rows = h.profile()
left = rows.avg()

cols, rows = h.fliphor().profile()
right = h.width - rows.avg()
width = right - left

cols, rows = v.profile()
top = cols.avg()

cols, rows = v.flipver().profile()
bottom = v.height - cols.avg()
height = bottom - top

# move the crop in by a margin
margin = 10
left += margin
top += margin
width -= 2 * margin
height -= 2 * margin

# and crop!
image = image.crop(left, top, width, height)

Чтобы сделать:

enter image description here

И, наконец, удалитьфон, размытие с большим радиусом и вычитание:

image = image.colourspace('b-w').gaussblur(70) - image

Чтобы сделать:

enter image description here

0 голосов
/ 24 сентября 2018

Вот одна из идей, как продолжить ...

Преобразование в HSV, затем начните в каждом углу и продвигайтесь к середине изображения, ища ближайший пиксель к каждому углу, который несколько насыщен иимеет оттенок, соответствующий вашему голубоватому окружающему прямоугольнику.Это даст вам 4 точки, отмеченные красным:

enter image description here

Теперь используйте перспективное преобразование, чтобы сдвинуть каждую из этих точек в угол, чтобы сделать изображениепрямолинейный.Я использовал ImageMagick, но вы должны увидеть, что я перевожу верхнюю левую красную точку в координатах (210,51) в верхний левый угол нового изображения в точке (0,0).Аналогично, верхняя правая красная точка в (1754,19) смещается в (2064,0).Команда ImageMagick в терминале:

convert wordsearch.jpg \
  -distort perspective '210,51,0,0 1754,19,2064,0 238,1137,0,1161 1776,1107,2064,1161' result.jpg

Это приводит к следующему:

enter image description here

Следующая проблема - неравномерное освещение, а именнонижний левый темнее, чем остальная часть изображения.Чтобы компенсировать это, я клонирую изображение и размываю его, чтобы удалить высокие частоты (просто размытие по прямоугольникам или усреднение по прямоугольникам), так что теперь оно представляет медленно меняющееся освещение.Затем я вычитаю изображение из этого, так что я эффективно удаляю вариации фона и оставляю только высокочастотные вещи - как ваши письма.Затем я нормализую результат, чтобы сделать белые белые и черные черными, а пороговое значение составляет 50%.

convert result.jpg -colorspace gray \( +clone -blur 50x50 \) \
   -compose difference -composite  -negate -normalize -threshold 50% final.jpg

enter image description here

Результат должен быть хорошим для сопоставления с шаблономесли вы знаете шрифт и буквы или для OCR, если вы не знаете.

0 голосов
/ 24 сентября 2018

Вот мои шаги для распознавания символов:

(1) detect the blue in hsv space, approx the inner blur contour and sort the corner points:
(2) find persprctive transform matrix and do perspective transform
(3) threshold it (and find characters)
(4) use `mnist` algorithms to recognize the chars

step (1) find the corners of the blur rect

Выбор правильной верхней и нижней границ ВПГ для определения цвета с помощью `cv :: inRange` (OpenCV)

enter image description here enter image description here

step (2) crop

enter image description here

step (3) threshold (and find the chars)

enter image description here enter image description here

step (4) on working...
0 голосов
/ 24 сентября 2018

Я думаю, что лучше удалить цвет вместо обрезки.

Это можно сделать с помощью opencv, см .: python - opencv morphologyEx. Удалить определенный цвет

...