Задать вопрос
@glu-dimaz

Какие способы есть подготовки изображения к дальнейшему распознаванию текста с помощью Python?

Задача состоит в следующем. Есть сертификат на экспорт автомобиля из Японии. Из него необходимо достать определенные значения(выделил зеленым на изображении):
6701b8aab6226354164852.jpeg
Это обычные сканы документов или просто картинки объединённые в .pdf формат, текст в которых - не определен(если открыть в каком-нибудь pdf редакторе).

Чтобы не мучаться с чтением всего документа, а потом выделением из него необходимых значений - я решил поступить наоборот - сначала выделить в документе +- необходимую область для распознавания. Наложив, 10 документов друг на друга в фотошопе, я нашел примерные координаты необходимых блоков для обрезки оригинального изображения и с помощью функции crop - обрезал изображения по примерным точкам.
image.crop(cpor_cords)
6701ba8640f45416238976.png
6701baa4ae6d7200267776.png
После чего, добавив яркости и контрастности, а так же - применив черно-белый фильтр - я обработал изображения. Далее подключил EasyOCR для распознавания текста на картинке. Результат, мягко сказать - был не очень. Из 20 документов - верно определялось 2-3 штуки. Попробовал ручками - убрать все на изображении кроме текста(границы ячеек, вводные знаки и т.д.) - тогда результат был куда лучше. Тогда уже решил провести следующую процедуру: обрезать обрезанные изображения:

width, height = final_image.size
pixel_data = []

for y in range(height):
        for x in range(width):
            color = pixels[x, y]
            pixel_data.append((x, y, color))

x1 = None
x2 = None
y1 = None
y2 = None

for pixel in pixel_data:
        x, y = pixel[0], pixel[1]
        r, g, b = pixel[2][:3]
        
        if y == 2 and r < 200 and g < 200 and b < 200:
            print(x)
            if x1 is None:
                #print(x,y,r,g,b)
                x1 = x
            x2 = x
        if type != 'serial':
            if x == 9:
                if r != 255 and g != 255 and b != 255:
                    if y1 is None:
                        y1 = y
                    y2 = y
        if type == 'serial':
            if x == 100:
                if r != 255 and g != 255 and b != 255:
                    if y1 is None:
                        y1 = y
            if x == 900:
                if r != 255 and g != 255 and b != 255:
                    y2 = y
  
if type != 'serial':
       x2 -= 23
       x1 += 20
   
crop_final = x1, y1, x2, y2
print('Croped: ',crop_final)

image2 = Image.open('final_output_' + str(type) + '.png')
cropped_image = image2.crop(crop_final)

То есть, логика была следующая: открываем изображение и разбираем его по пикселям и цветам в нем.
Проходимся по ширине в 9 пикселей. Если у нас не задана y1, а цвет в данной точки не белый - то y1 равно данным координатам. Последняя точка y2 - последняя точка на данной ширине, которая не равна цвету 255,255,255. Для серийного номера брал 2 точки x - это на 100 пикселе и на 900-м

Тут я уже столкнулся с другой проблемой: Либо неопределенна координаты y2 или вообще некорректно. Зачастую, в необходимых областях - по мимо границы ячейки - находился либо текст с других ячеек - либо не было ничего и y2 = ширине изображения. Менял точки прохода: х = 12,15,20 и т.д. - так как это сканы, где то документ положили к верхнему правому углу сканера, где то к нижнему левому, а где то вовсе наклон 5*. Тогда решил поменять алгоритм - так как серийники +- обрезались ровно и документы имели четко один и тот же размер - я решил использовать точку G. Я искал точку отсчета - верхний левый угол ячейки серийного номера. И если мы знаем данную точку - мы рассчитываем от нее уже расстояния до других ячеек по пикселям. Но кривые обрезки все равно достаточно часто проскакивали - либо точка G находилась чуть выше границы ячейки таблицы, или чуть ниже границы.

В общем. Неделю ковырял - не знаю что уже можно придумать? Есть ли какие-нибудь альтернативы, чтобы необходимые области обрезались как надо? В идеале - если на изображение применен фильтр, яркость и контрастность - в 95% текст читается корректно - а этого более чем достаточно.
  • Вопрос задан
  • 124 просмотра
Подписаться 1 Простой 1 комментарий
Решения вопроса 1
@U235U235
Используйте библиотеку OpenCV и функцию cv2.connectedComponentsWithStats. Отфильтруйте компоненты по высоте. Всё.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы