14

Sto cercando un metodo di classificazione delle pagine scansionate che consistono in gran parte di testo.classificazione Immagine in python

Qui sono i particolari del mio problema. Ho una vasta collezione di documenti scansionati e ho bisogno di rilevare la presenza di determinati tipi di pagine all'interno di questi documenti. Ho intenzione di "scoppiare" i documenti nelle loro pagine componenti (ognuna delle quali è un'immagine individuale) e classificare ciascuna di queste immagini come "A" o "B". Ma non riesco a capire il modo migliore per farlo.

Maggiori dettagli:

  • mi hanno numerosi esempi di "A" e "B" le immagini (pagine), quindi posso fare apprendimento supervisionato.
  • Non è chiaro a me come a migliori caratteristiche estrarre da queste immagini per la formazione. Per esempio. Quali sono queste caratteristiche?
  • Le pagine vengono occasionalmente leggermente ruotate, quindi sarebbe bello se la classificazione fosse alquanto insensibile alla rotazione e (in misura minore) al ridimensionamento.
  • Vorrei una soluzione cross-platform, in posizione ideale nel puro pitone o utilizzando librerie comuni.
  • ho pensato di usare OpenCV, ma questa sembra una soluzione di "peso".

EDIT:

  • La "A" e "B" pagine differire dal fatto che le pagine "B" hanno forme su di loro con la stessa struttura generale, compresa la presenza di un codice a barre. Le pagine "A" sono testo libero.
+0

In cosa differiscono? Font? Dimensione? Potresti OCR una parte di esso (un titolo o autore in un colpo di testa?) –

+0

Nick, ho aggiunto una modifica per chiarire su questo. In realtà, il mio obiettivo è gettare via tutto * dopo * le pagine B perché non devo registrarle. Quindi, ho davvero bisogno di rilevarli prima di fare qualsiasi OCR. – Kyle

+3

Questo è un bel problema difficile - a meno che la vostra collezione è davvero eccezionale, non sarebbe più facile solo per categorizzare manualmente le pagine come 'A' o' B'? Potresti scrivere una piccola app GUI per visualizzarli a turno in modo da poter semplicemente premere un tasto per pagina. – katrielalex

risposta

4

In primo luogo, vorrei dire che a mio parere OpenCV è un ottimo strumento per questo tipo di manipolazione. Inoltre, ha un'interfaccia python ben descritta here.

OpenCV è altamente ottimizzato e il tuo problema non è facile.

[GLOBAL EDIT: riorganizzazione delle mie idee]

Ecco alcuni idea di caratteristiche che potrebbero essere utilizzati:

  • Per rilevare i codici a barre si dovrebbe forse cercare di fare una distanza trasformare (DistTransform in OpenCV) se il codice a barre è isolato. Forse sarai in grado di trovare facilmente i punti di interesse con le corrispondenze o le forme. Penso che sia fattibile perché i codici a barre hanno la stessa forma (dimensione, ecc.). Il punteggio dei punti di interesse potrebbe essere utilizzato come caratteristica.

  • I momenti dell'immagine possono essere utili qui perché si hanno diversi tipi di strutture globali. Questo sarà forse sufficiente per fare distinzione tra & pagine B (vedi there per la funzione OpenCV) (otterrete descrittori invarianti tra l'altro :))

  • Si dovrebbe forse cercare di calcolare vertical gradient e horizontal gradient. Un codice a barre è un luogo specifico in cui vertical gradient == 0 e horizontal gradient! = 0. Questo vantaggio principale è il basso costo di queste operazioni dal momento che il tuo obiettivo è solo quello di verificare se c'è una tale zona sulla tua pagina.È possibile trovare zona di interesse e di usare il suo punteggio come caratteristica

Una volta che avete le vostre caratteristiche, si può provare a fare supervised learning e test di generalizzazione. Il tuo problema richiede pochissimo false negative (perché stai per buttare via alcune pagine) quindi dovresti valutare la tua performance con le curve ROC e guardare attentamente la sensibilità (che dovrebbe essere alta). Per la classificazione, è possibile utilizzare la regressione con penalizzazione lazo per trovare le migliori caratteristiche. Il post di whatnick fornisce anche idee per le merci e altri descrittori (forse più generali).

2

Quindi si desidera essere in grado di distinguere tra due tipi di pagine utilizzando elementi specifici, in pratica la presenza di codici a barre. Ci sono due passaggi:

  1. funzione di estrazione (computer vision): trova punti di interesse o linee che sarebbero caratteristiche specifiche di codici a barre e non in testo.

  2. classificazione binaria (apprendimento statistico): determinare se è presente o meno un codice a barre, in base alle funzioni estratte.


Trattare con il primo passo, si dovrebbe assolutamente avere uno sguardo alla Hough transform. È ideale per identificare le linee in un'immagine e potrebbe essere utile per il rilevamento dei codici a barre. Leggi questi two pages per esempio. Qui ci sono examples con OpenCV.


Circa il secondo passo, le classificazioni più utile sarebbe basata su:

  • vicini più vicini k
  • regressione logistica
  • foresta casuale (davvero ben implementato in R, ma lo faccio non so di Python)
+0

Orange Learning kit ha una bella implementazione di foresta casuale che ho usato prima di trovare quella in R. – whatnick

9

Risponderò in 3 parti poiché il tuo problema è chiaramente grande e Mi raccomando metodo manuale con manodopera a basso costo, se la raccolta di pagine non superi un 1000.

Parte 1: Feature Extraction - Hai una vasta gamma di funzioni tra cui scegliere nel campo rilevamento di oggetti. Poiché uno dei tuoi requisiti è l'invarianza di rotazione, ti consiglio la classe di funzioni SIFT/SURF. Si potrebbero anche trovare angoli Harris ecc. Adatti. Decidere quali funzionalità utilizzare può richiedere conoscenze specialistiche e se si dispone di potenza di calcolo, consiglierei di creare un bel melting pot di funzionalità e di passarlo attraverso uno stimatore basato sull'importanza basato sulla formazione del classificatore.

Parte 2: Classificatore Selection - Sono un grande fan del Random Forest classificatore. Il concetto è molto semplice da comprendere ed è altamente flessibile e non parametrico. La sintonizzazione richiede pochissimi parametri e puoi anche eseguirla in una modalità di selezione dei parametri durante l'allenamento supervisionato.

Parte 3: Implementazione - Python in sostanza è un linguaggio di colla. Le implementazioni di Python puro per l'elaborazione delle immagini non saranno mai molto veloci. Raccomando di utilizzare una combinazione di OpenCV per il rilevamento di funzionalità e R per lavori statistici e classificatori.

La soluzione può sembrare eccessivamente ingegnerizzata, ma l'apprendimento automatico non è mai stato un compito semplice, anche quando la differenza tra le pagine è semplicemente che si tratta delle pagine di sinistra e di destra di un libro.

+0

SIFT sono sicuramente una buona idea ma in questo caso, possiamo forse definire direttamente caratteristiche più personalizzate a causa della nostra conoscenza precedente (presenza di codice a barre o di testo in chiaro, ecc ...) (vedere il mio post). Usare una formazione per classificatore per scoprire come combinare le nostre caratteristiche per dare una risposta è una buona scelta. (+1 in generale per il post) – ThR37

+0

@wok: Penso che whatnick abbia voluto proporre un approccio più generale (e pulito) del problema invece di andare direttamente più in profondità nella domanda "quale funzione dovrei usare?". Dobbiamo tenere presente che il codice a barre non è l'unica soluzione a questo problema e tenta di combinare diversi modi. Il tuo link è molto interessante in tutti i casi. – ThR37

+0

risposta eccellente. Ho visto SIFT e SURF ma, purtroppo, la mia applicazione è commerciale e SIFT è brevettato. – Kyle

0

Si può provare a costruire un modello caricando i dati di allenamento di A e B di per demo.nanonets.ai (da usare gratuitamente)

1) Carica i dati di allenamento qui:

demo.nanonets.ai

2) Quindi interrogare l'API utilizzando la seguente (codice 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) la risposta appare come:

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