14

Estoy buscando un método para clasificar las páginas escaneadas que consisten principalmente en texto.Clasificación de imágenes en python

Aquí están los detalles de mi problema. Tengo una gran colección de documentos escaneados y necesito detectar la presencia de ciertos tipos de páginas dentro de estos documentos. Planeo "estallar" los documentos en sus páginas componentes (cada una de las cuales es una imagen individual) y clasificar cada una de estas imágenes como "A" o "B". Pero no puedo encontrar la mejor manera de hacer esto.

Más detalles:

  • que tienen numerosos ejemplos de "A" y "B" imágenes (páginas), por lo que pueden hacer el aprendizaje supervisado.
  • No me queda claro cómo extraer mejor las características de estas imágenes para el entrenamiento. P.ej. ¿Cuáles son esas características?
  • Las páginas se rotan ocasionalmente ligeramente, por lo que sería genial si la clasificación fuera algo insensible a la rotación y (en menor medida) al escalado.
  • Me gustaría una solución multiplataforma, idealmente en Python puro o usando bibliotecas comunes.
  • He pensado en usar OpenCV, pero esto parece ser una solución de "gran peso".

EDIT:

  • La "A" y "B" páginas se diferencian en que las páginas "B" tienen formas en ellos con la misma estructura general, incluyendo la presencia de un código de barras. Las páginas "A" son texto libre.
+0

¿Cómo difieren? ¿Fuente? ¿Tamaño? ¿Podrías simplemente OCR alguna parte de él (un título o autor en un encabezado?) –

+0

Nick, agregué una edición para aclarar sobre eso. En realidad, mi objetivo es tirar todo * después de * las páginas B porque no tengo que OCR. Entonces, realmente necesito detectarlos antes de hacer cualquier OCR. – Kyle

+3

Este es un problema bastante difícil: a menos que su colección sea realmente tremenda, ¿no sería más fácil categorizar manualmente las páginas como 'A' o' B'? Podrías escribir una pequeña aplicación GUI para mostrarlas a su vez, de modo que solo puedas presionar una tecla por página. – katrielalex

Respuesta

4

En primer lugar, me gustaría decir que en mi opinión OpenCV es una muy buena herramienta para este tipo de manipulación. Además, tiene una interfaz de Python bien descrita here.

OpenCV está altamente optimizado y su problema no es fácil.

[EDIT GLOBAL: reorganización de mis ideas]

He aquí algunos idea de las características que se podría utilizar:

  • Para la detección de los códigos de barras se debe tal vez tratar de hacer una transformada de distancia (DistTransform en OpenCV) si el código de barras está aislado. Tal vez puedas encontrar puntos de interés fácilmente con match o matchShapes. Creo que es factible porque los códigos de barras deben tener la misma forma (tamaño, etc.). El puntaje de los puntos de interés podría usarse como una característica.

  • Los momentos de la imagen podrían ser útiles aquí porque tiene diferentes tipos de estructuras globales. Esto será suficiente para hacer tal distinción entre un & páginas B (ver there para la función OPENCV) (obtendrá descriptores invariantes por cierto :))

  • Usted debe intentar quizá para calcular vertical gradient y horizontal gradient. Un código de barras es un lugar específico donde vertical gradient == 0 y horizontal gradient! = 0. Esta ventaja principal es el bajo costo de estas operaciones, ya que su objetivo es solo verificar si existe tal zona en su página.Puede encontrar zona de interés y utilizar su puntuación como una característica

vez que tenga sus características, se puede tratar de hacer supervised learning y la prueba de generalización. Su problema requiere muy pocos false negative (porque va a tirar algunas páginas) por lo que debe evaluar su rendimiento con curvas ROC y observar cuidadosamente la sensibilidad (que debería ser alta). Para la clasificación, puede usar regresión con penalización de lazo para encontrar las mejores características. La publicación de whatnick también da ideas de productos y otros descriptores (tal vez más generales).

2

Así que desea poder distinguir dos tipos de páginas con elementos específicos, básicamente, la presencia de códigos de barras. Hay dos pasos:

  1. extracción de características (visión por ordenador): buscar puntos de interés o líneas que serían características específicas de códigos de barras y no de texto.

  2. clasificación binaria (aprendizaje estadístico): determine si hay un código de barras o no, en función de las características extraídas.


Tratar con el primer paso, debería echar un vistazo a la Hough transform. Es ideal para identificar líneas en una imagen y podría ser útil para la detección de códigos de barras. Lea estos two pages por ejemplo. Aquí están examples con OpenCV.


Sobre el segundo paso, las clasificaciones más útiles se basaría en:

  • k vecinos más próximos
  • regresión logística
  • bosque aleatorio (muy bien aplicado en la I, pero yo no sabe sobre Python)
+0

Orange Learning kit tiene una buena implementación de bosque aleatorio que solía utilizar antes de encontrar el de R. – whatnick

9

Voy a responder en 3 partes ya que su problema es claramente grande y Yo recomendaría altamente método manual con mano de obra barata, si la colección de páginas no supera un

1000.

Parte 1: Extracción Característica - Usted tiene una gran variedad de características para elegir en el campo de detección de objetos. Como uno de sus requisitos es la invarianza de rotación, recomendaría la clase de características SIFT/SURF. También puede encontrar las esquinas de Harris, etc., adecuadas. Decidir qué características usar puede requerir conocimiento experto y si tiene poder de cómputo, le recomendaría crear un buen crisol de características y pasarlo a través de un estimador de importancia basado en el entrenamiento del clasificador.

Parte 2: Clasificador Selección - yo soy un gran fan de la Random Forest clasificador. El concepto es muy simple de entender y es altamente flexible y no paramétrico. El ajuste requiere muy pocos parámetros y también puede ejecutarlo en un modo de selección de parámetros durante el entrenamiento supervisado.

Parte 3: Implementación - Python, en esencia, es un lenguaje de pegamento. Las implementaciones de Python puro para el procesamiento de imágenes nunca serán muy rápidas. Recomiendo usar una combinación de OpenCV para detección de características y R para trabajo estadístico y clasificadores.

La solución puede parecer sobrediseñada pero el aprendizaje automático nunca ha sido una tarea simple, incluso cuando la diferencia entre las páginas es simplemente que son las páginas izquierda y derecha de un libro.

+0

SIFT son ciertamente una buena idea, pero en este caso, quizás podamos definir características directamente más personalizadas debido a nuestro conocimiento previo (presencia de código de barras o de texto plano, etc. ...) (véase mi publicación). Usar una capacitación de clasificador para encontrar cómo combinar nuestras características para dar una respuesta es una buena opción. (+1 en general para la publicación) – ThR37

+0

@wok: Creo que Whatnick quería proponer un enfoque más general (y claro) del problema en lugar de profundizar directamente en la pregunta "¿qué función debo usar?". Debemos tener en cuenta que el código de barras no es la única solución para este problema y tratamos de combinar diferentes maneras. Tu enlace es muy interesante en todos los casos. – ThR37

+0

excelente respuesta. Vi SIFT & SURF pero, por desgracia, mi aplicación es comercial y SIFT está patentada. – Kyle

0

Usted puede intentar la construcción de un modelo mediante la subida de sus datos de entrenamiento de A y B a demo.nanonets.ai (de uso gratuito)

1) cargar los datos de entrenamiento aquí:

demo.nanonets.ai

2) A continuación, consultar la API mediante el siguiente (Código de 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 respuesta será similar a:

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