14

Poszukuję metody klasyfikacji zeskanowanych stron, które składają się w dużej mierze z tekstu.Klasyfikacja obrazu w pytonie

Oto szczegóły dotyczące mojego problemu. Mam duży zbiór zeskanowanych dokumentów i muszę wykryć obecność pewnych rodzajów stron w tych dokumentach. Planuję "rozłożyć" dokumenty na ich strony składowe (każda z nich jest indywidualnym obrazem) i zaklasyfikować każdy z tych obrazów jako "A" lub "B". Ale nie mogę wymyślić najlepszego sposobu na zrobienie tego.

Więcej szczegółów:

  • mam liczne przykłady "A" i "B" obrazów (stron), więc mogę zrobić nadzorowanego uczenia się.
  • Nie jest dla mnie jasne, jak najlepiej wyodrębnić elementy z tych obrazów do treningu. Na przykład. Jakie są te funkcje?
  • Strony są czasami nieco obrócone, więc byłoby świetnie, gdyby klasyfikacja była nieco niewrażliwa na obrót i (w mniejszym stopniu) skalowanie.
  • Chciałbym rozwiązanie wieloplatformowe, najlepiej w czystym Pythonie lub przy użyciu wspólnych bibliotek.
  • Myślałem o używaniu OpenCV, ale wygląda na to, że jest to rozwiązanie "ciężkie".

Edycja:

  • „A” i „B” strony różnią się tym, że strona „B” mają na nich form o takiej samej ogólnej strukturze, w tym obecności kodu kreskowego. Strony "A" są wolnym tekstem.
+0

Czym się różnią? Czcionka? Rozmiar? Czy możesz po prostu OCR część (tytuł lub autor w nagłówku?) –

+0

Nick, dodałem edycję, aby wyjaśnić na ten temat. Właściwie moim celem jest wyrzucenie wszystkiego * po * stronach B, ponieważ nie muszę ich OCR. Tak więc naprawdę muszę je wykryć przed wykonaniem jakiegokolwiek OCR. – Kyle

+3

To jest dość trudny problem - chyba że twoja kolekcja jest naprawdę olbrzymia, czy nie byłoby prostsze ręczne kategoryzowanie stron jako "A" lub "B"? Możesz napisać małą aplikację GUI, aby wyświetlić je po kolei, tak abyś mógł nacisnąć tylko jeden klawisz na stronę. – katrielalex

Odpowiedz

4

Po pierwsze, chciałbym powiedzieć, że moim zdaniem OpenCV jest bardzo dobrym narzędziem do tego rodzaju manipulacji. Co więcej, ma interfejs Pythona dobrze opisany here.

OpenCV jest wysoce zoptymalizowany, a Twój problem nie jest łatwy.

[GLOBAL EDIT: reorganizacja moich pomysłów]

Oto kilka pomysł funkcji, które mogą być wykorzystane:

  • do wykrywania kodów kreskowych należy może spróbować zrobić dystans transformacji (DistTransform w OpenCV), jeśli kod kreskowy jest izolowany. Być może będziesz w stanie znaleźć zainteresowanie punktowo za pomocą dopasowania lub matchShapes. Myślę, że jest to wykonalne, ponieważ kody kreskowe mają ten sam kształt (rozmiar, itp.). Wynik punktów procentowych może być wykorzystany jako funkcja.

  • Chwile obrazu mogą być przydatne, ponieważ masz różne rodzaje struktur globalnych. Będzie to być może wystarczające do dokonywania rozróżnienia między & stron B (patrz there dla funkcji OpenCV) (dostaniesz niezmienne deskryptory przy okazji :))

  • Powinieneś może spróbować obliczyć vertical gradient i horizontal gradient. Kod kreskowy to określone miejsce, w którym vertical gradient == 0 i horizontal gradient! = 0. Główną zaletą jest niski koszt tych operacji, ponieważ Twoim celem jest tylko sprawdzenie, czy na twojej stronie istnieje taka strefa.Można znaleźć strefę procentowej i używać jej wynik jako cecha

Gdy masz swoje funkcje, można spróbować zrobić supervised learning i przetestować uogólnienie. Twój problem wymaga bardzo niewielu false negative (ponieważ zamierzasz wyrzucić kilka stron), więc powinieneś ocenić swoją wydajność za pomocą krzywych ROC i uważnie przyjrzeć się wrażliwości (która powinna być wysoka). Do klasyfikacji można użyć regresji z penetracją lasso, aby znaleźć najlepsze funkcje. Post of whatnick podaje również pomysły na towary i inne deskryptory (może bardziej ogólne).

2

Chcesz więc odróżnić dwa rodzaje stron za pomocą określonych elementów - w zasadzie obecność kodów kreskowych. Istnieją dwa etapy:

  1. cechą ekstrakcji (computer vision): znaleźć punkty procentowe lub linie, które byłyby specyficzne cechy kodów kreskowych, a nie tekstu.

  2. klasyfikacja binarna (uczenie się statystyczne): określić, czy istnieje kod paskowy, czy nie, na podstawie wyodrębnionych funkcji.


czynienia z pierwszego etapu, powinno się spojrzeć na Hough transform. Jest idealny do identyfikacji linii na obrazie i może być przydatny do wykrywania kodów kreskowych. Przeczytaj na przykład te two pages. Oto examples z OpenCV.


O drugim etapie, najbardziej użyteczne będą opierały się na:

  • k najbliższych sąsiadów
  • regresji logistycznej
  • random forest (naprawdę dobrze wdrożony w R, ale robię nie wiem o Pythonie)
+0

Pomarańczowy zestaw do nauki ma ładną losową implementację lasu, której używałem, zanim znalazłem tę w R. – whatnick

9

Będę odpowiadać w 3 częściach, ponieważ twój problem jest wyraźnie duży i Gorąco polecam metodą ręczną z taniej siły roboczej, czy zbiór stron nie przekracza 1000.

Część 1: Feature Extraction - Masz bardzo duży wachlarz funkcji do wyboru w dziedzinie wykrywania obiektów. Ponieważ jednym z twoich wymagań jest niezmienność rotacji, polecam klasę funkcji SIFT/SURF. Możesz również znaleźć odpowiednie narożniki Harris. Wybór funkcji do wykorzystania może wymagać specjalistycznej wiedzy, a jeśli masz moc obliczeniową, poleciłabym stworzyć fajny tygiel funkcji i przekazać go przez oceniany na podstawie szkolenia klasyfikator oparty na klasyfikatorze.

Część 2: klasyfikator Selection - Jestem wielkim fanem Random Forest klasyfikatora. Koncepcja jest bardzo prosta do uchwycenia i jest bardzo elastyczna i nieparametryczna. Strojenie wymaga bardzo niewielu parametrów i można go również uruchomić w trybie wyboru parametrów podczas nadzorowanego szkolenia.

Część 3: Wdrożenie - Python w istocie jest językiem kleju. Implementacje czystego Pythona do przetwarzania obrazu nigdy nie będą bardzo szybkie. Polecam użycie kombinacji OpenCV do wykrywania cech i R dla pracy statystycznej i klasyfikatorów.

Rozwiązanie może wydawać się zbyt skomplikowane, ale uczenie maszynowe nigdy nie było prostym zadaniem, nawet jeśli różnica między stronami polega po prostu na tym, że są one lewą i prawą stroną książki.

+0

SIFT to z pewnością dobry pomysł, ale w tym przypadku możemy zdefiniować bezpośrednio bardziej dostosowane funkcje ze względu na naszą wcześniejszą wiedzę (obecność kodu kreskowego lub tekstu jawnego, itp.) (por. mój post). Korzystanie ze szkolenia klasyfikatora w celu znalezienia sposobu łączenia naszych funkcji w celu udzielenia odpowiedzi jest dobrym wyborem. (+1 ogólnie dla posta) – ThR37

+0

@wok: Myślę, że whatnick chciał zaproponować bardziej ogólne (i czyste) podejście do problemu, zamiast iść bezpośrednio głębiej w pytanie "jakiej cechy powinienem użyć?". Musimy pamiętać, że kod kreskowy nie jest jedynym rozwiązaniem tego problemu i próbuje łączyć różne sposoby. Twój link jest bardzo interesujący we wszystkich przypadkach. – ThR37

+0

Doskonała odpowiedź. Widziałem SIFT & SURF, ale, niestety, moja aplikacja jest komercyjna, a SIFT opatentowany. – Kyle

0

Można spróbować budowy modelu, przesyłając swoje dane szkoleniowe A i B do demo.nanonets.ai (swobodnie korzystać)

1) Dodaj dane treningowe tutaj:

demo.nanonets.ai

2) Następnie kwerendy API używając następującego kodu (Python):

import requests 
import json 
import urllib 
model_name = "Enter-Your-Model-Name-Here" 
url = "https://cdn.pixabay.com/photo/2012/04/24/12/13/letter-39694_960_720.png" 
files = {'uploadfile': urllib.urlopen(url).read()} 
url = "http://demo.nanonets.ai/classify/?appId="+model_name 
r = requests.post(url, files=files) 
print json.loads(r.content) 

3) reakcja wygląda następująco:

{ 
    "message": "Model trained", 
    "result": [ 
    { 
     "label": "A", 
     "probability": 0.97 
    }, 
    { 
     "label": "B", 
     "probability": 0.03 
    } 
    ] 
}