2017-07-10 35 views
15

Mam kilka tysięcy plików PDF zawierających obrazy B (1bit) B & ze zdigitalizowanych formularzy papierowych. Próbuję OCR niektóre pola, ale kiedyś pisanie jest zbyt słaby:Wstępnie przetwarzanie słabo zeskanowanych, ręcznie pisanych cyfr

enter image description here

Właśnie dowiedziałem się o przekształceń morfologicznych. Są naprawdę fajne !!! Czuję się, jakbym ich nadużywał (tak jak robiłem to z wyrażeń regularnych, kiedy uczyłem się Perla).

Jestem zainteresowany tylko w dzień, 06.07.2017:

im = cv2.blur(im, (5, 5)) 
plt.imshow(im, 'gray') 

enter image description here

ret, thresh = cv2.threshold(im, 250, 255, 0) 
plt.imshow(~thresh, 'gray') 

enter image description here

Osoby wypełniające formularz ten wydaje się mieć pewne lekceważenie siatkę, więc starałem się go pozbyć. Jestem w stanie wyizolować linię poziomą to transform:

horizontal = cv2.morphologyEx(
    ~thresh, 
    cv2.MORPH_OPEN, 
    cv2.getStructuringElement(cv2.MORPH_RECT, (100, 1)), 
) 
plt.imshow(horizontal, 'gray') 

enter image description here

mogę pionowe linie, a także:

plt.imshow(horizontal^~thresh, 'gray') 

ret, thresh2 = cv2.threshold(roi, 127, 255, 0) 
vertical = cv2.morphologyEx(
    ~thresh2, 
    cv2.MORPH_OPEN, 
    cv2.getStructuringElement(cv2.MORPH_RECT, (2, 15)), 
    iterations=2 
) 
vertical = cv2.morphologyEx(
    ~vertical, 
    cv2.MORPH_ERODE, 
    cv2.getStructuringElement(cv2.MORPH_RECT, (9, 9)) 
) 
horizontal = cv2.morphologyEx(
    ~horizontal, 
    cv2.MORPH_ERODE, 
    cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7)) 
) 
plt.imshow(vertical & horizontal, 'gray') 

enter image description here

Teraz mogę uzyskać Pozbądź się siatki:

plt.imshow(horizontal & vertical & ~thresh, 'gray') 

enter image description here

Najlepszym Dostałem to, ale 4 jest nadal podzielony na 2 części:

plt.imshow(cv2.morphologyEx(im2, cv2.MORPH_CLOSE, 
    cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))), 'gray') 

enter image description here

Prawdopodobnie w tym momencie lepiej jest użyć cv2.findContours a niektóre heurystyki w celu zlokalizowania każdej cyfry, ale zastanawiałem się:

  1. powinienem dać się i żądasz ponownego skanowania wszystkich dokumentów w skali szarości?
  2. Czy istnieją lepsze metody w celu wyodrębnienia i zlokalizowania słabych cyfr?
  3. Czy znasz jakieś przekształcenie morfologiczne, aby dołączyć do przypadków takich jak "4"?

[aktualizacja]

Czy ponowne skanowanie dokumentów zbyt wymagający? Jeśli to nie jest wielki kłopot wierzę, to lepiej, aby wejść jakości wyższej niż szkolenia i stara się udoskonalić swój model, aby wytrzymać hałaśliwych i nietypowych danych

Odrobina kontekstu: jestem nikt nie pracuje w agencja publiczna w Brazylii. Cena rozwiązań ICR zaczyna się od 6 cyfr, więc nikt nie wie, że jeden facet może napisać rozwiązanie ICR w domu.Jestem wystarczająco naiwny, by uwierzyć, że mogę udowodnić, że się mylą. Te dokumenty PDF znajdowały się na serwerze FTP (około 100K plików) i zostały zeskanowane tylko po to, aby pozbyć się wersji drzewa martwego. Prawdopodobnie uda mi się uzyskać oryginalną formę i samemu przeskanować, ale musiałbym poprosić o oficjalne wsparcie - skoro jest to sektor publiczny, chciałbym, aby ten projekt był jak najdalej pod ziemią. Mam teraz wskaźnik błędu 50%, ale jeśli to podejście jest ślepym zaułkiem, nie ma sensu go ulepszać.

+1

Czy ponowne skanowanie dokumentów jest zbyt wymagające? Jeśli nie jest to wielki problem, uważam, że lepiej jest uzyskać dane wejściowe o wyższej jakości niż trening i próbować udoskonalić model, aby wytrzymać hałaśliwe i nietypowe dane. – DarkCygnus

+0

@GrayCygnus: Musiałbym przekroczyć ocean biurokracji i bezwładności, ale jest to możliwe . Prawdopodobnie sam będę musiał wykonać całą pracę ręczną. –

+0

Poproszę również o zapoznanie się z tym [tutorialem] (http://www.pyimagesearch.com/2017/07/10/using-tesseract-ocr-python/) (z tego samego źródła co ten, który w mojej odpowiedzi na poprzednie pytanie), gdzie przedstawiają Tesseract (opakowanie OCR Engine Googles) jako świetne narzędzie do robienia OCR. Znalazłem także [ten dokument] (http://worldcomp-proceedings.com/proc/p2016/ICA3674.pdf), który wyjaśnia, w jaki sposób poprawić rozpoznawanie znaków za pomocą K-najbliższych sąsiadów z metryką odległości euklidesowej. Powodzenia przemierzając ten ocean :) – DarkCygnus

Odpowiedz

7

Może z pewnego rodzaju zbiorem Active contour model? Na przykład, znalazłem tej biblioteki: https://github.com/pmneila/morphsnakes

zajął twoje ostateczne „4” numer:

enter image description here

Po jakimś szybkim szczypanie (bez faktycznego zrozumienia parametry, więc może to być możliwe, aby uzyskać lepszy wynik) mam ten:

enter image description here

z następującego kodu (ja również włamał się do morphsnakes.py trochę t o zapisz obrazy):

import morphsnakes 

import numpy as np 
from scipy.misc import imread 
from matplotlib import pyplot as ppl 

def circle_levelset(shape, center, sqradius, scalerow=1.0): 
    """Build a binary function with a circle as the 0.5-levelset.""" 
    grid = np.mgrid[list(map(slice, shape))].T - center 
    phi = sqradius - np.sqrt(np.sum((grid.T)**2, 0)) 
    u = np.float_(phi > 0) 
    return u 

#img = imread("testimages/mama07ORI.bmp")[...,0]/255.0 
img = imread("four.png")[...,0]/255.0 

# g(I) 
gI = morphsnakes.gborders(img, alpha=900, sigma=3.5) 

# Morphological GAC. Initialization of the level-set. 
mgac = morphsnakes.MorphGAC(gI, smoothing=1, threshold=0.29, balloon=-1) 
mgac.levelset = circle_levelset(img.shape, (39, 39), 39) 

# Visual evolution. 
ppl.figure() 
morphsnakes.evolve_visual(mgac, num_iters=50, background=img)