Определить угол ориентации изображения на основе направления текста - PullRequest
1 голос
/ 19 сентября 2019

Я работаю над задачей OCR, чтобы извлечь информацию из нескольких документов, удостоверяющих личность.Одной из проблем является ориентация отсканированного изображения.Необходимо исправить ориентацию отсканированного изображения PAN, Aadhaar, водительских прав или любого другого удостоверения личности.

Уже опробованы все предлагаемые подходы в Stackoverflow и других форумах, таких как OpenCV minAreaRect, Hough Lines Transforms, FFT,омография, tesseract osd с psm 0. Ничего не работает.

Логика должна возвращать угол направления текста - 0, 90 и 270 градусов.Приложены изображения 0, 90 и 270 градусов.Это не об определении асимметрии. enter image description here

1 Ответ

1 голос
/ 20 сентября 2019

Вот подход, основанный на предположении, что большая часть текста перекошена в одну сторону.Идея состоит в том, что мы можем определить угол на основе расположения основной текстовой области

  • . Преобразовать изображение в оттенки серого и размытие по Гауссу
  • Адаптивный порог для получения двоичного изображения
  • Поиск контуров и фильтрация по области контуров
  • Создание отфильтрованных контуров на маске
  • Разделение изображения по горизонтали или вертикали в зависимости от ориентации
  • Подсчет количества пикселей в каждой половине

После преобразования в оттенки серого и размытие по Гауссу мы адаптируем порог для получения двоичного изображения

enter image description here

Отсюдамы находим контуры и фильтруем, используя область контура для удаления мелких шумовых частиц и большой границы.Мы рисуем любые контуры, которые пропускают этот фильтр, на маску

enter image description here

Чтобы определить угол, мы разделим изображение пополам на основе размера изображения.Если width > height, то это должно быть горизонтальное изображение, поэтому мы делим пополам по вертикали.если height > width, то это должно быть вертикальное изображение, поэтому мы делим пополам по горизонтали

enter image description here enter image description here

Теперь, когда мыесть две половины, мы можем использовать cv2.countNonZero(), чтобы определить количество белых пикселей на каждой половине.Вот логика для определения угла:

if horizontal
    if left >= right 
        degree -> 0
    else 
        degree -> 180
if vertical
    if top >= bottom
        degree -> 270
    else
        degree -> 90

влево 9703

вправо 3975

Следовательно, изображение составляет 0 градусов.Вот результаты из других направлений

enter image description here enter image description here enter image description here enter image description here

слева 3975

справа 9703

Можно сделать вывод, что изображение перевернуто на 180 градусов

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

enter image description here enter image description here enter image description here enter image description here

enter image description here

сверху 3947

снизу 9550

Таким образом, результат равен 90градусы

import cv2
import numpy as np

def detect_angle(image):
    mask = np.zeros(image.shape, dtype=np.uint8)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray, (3,3), 0)
    adaptive = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,15,4)

    cnts = cv2.findContours(adaptive, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]

    for c in cnts:
        area = cv2.contourArea(c)
        if area < 45000 and area > 20:
            cv2.drawContours(mask, [c], -1, (255,255,255), -1)

    mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
    h, w = mask.shape

    # Horizontal
    if w > h:
        left = mask[0:h, 0:0+w//2]
        right = mask[0:h, w//2:]
        left_pixels = cv2.countNonZero(left)
        right_pixels = cv2.countNonZero(right)
        return 0 if left_pixels >= right_pixels else 180
    # Vertical
    else:
        top = mask[0:h//2, 0:w]
        bottom = mask[h//2:, 0:w]
        top_pixels = cv2.countNonZero(top)
        bottom_pixels = cv2.countNonZero(bottom)
        return 90 if bottom_pixels >= top_pixels else 270

if __name__ == '__main__':
    image = cv2.imread('1.png')
    angle = detect_angle(image)
    print(angle)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...