¿Cuáles son los mejores métodos para el reconocimiento robusto de caracteres en MATLAB u OPENCV?

A2A’d …

Solo he trabajado en OpenCV recientemente … ha pasado un tiempo desde que codifiqué seriamente en MATLAB. También abordo el reconocimiento de imágenes desde un fondo de minería de datos / ML … así que solo puedo sugerir un enfoque en estos dominios. Un verdadero experto en OCR probablemente le dará una mejor respuesta.

Mi técnica general es:

1.) Preproceso
2.) Extraer características
3.) Clasificar

Preprocesamiento

Estandarice las imágenes por escala y ubicación. Por ejemplo:


Ahora, creo que tienes una opción aquí. Puede extraer características en este punto O puede probar una idea más nueva con respecto al preprocesamiento de imágenes y luego extraer características. Analicemos primero esta nueva idea. Algunas personas muy inteligentes han sugerido distorsionar su conjunto de entrenamiento antes de intentar clasificar los personajes. La idea se presenta aquí: Página en arxiv.org.

Básicamente, creas copias distorsionadas de cada dígito en tu conjunto de entrenamiento de esta manera:


Agregar ruido aleatorio o “jitter” a la imagen es lo mismo que agregar regularización L2 (también conocida como disminución de peso) a su clasificador, que en mi experiencia, aumenta la solidez de la clasificación. Supongo que introducir la rotación en el conjunto de entrenamiento hace que su clasificador sea más robusto para las imágenes rotadas. (Por supuesto, simplemente puede escribir código para normalizar sus datos para la rotación, pero he tenido mejores resultados al agregar estas imágenes distorsionadas a mi conjunto de entrenamiento). He pegado un código Python (probablemente malo) a continuación para normalizar y luego distorsionar las imágenes de entrenamiento abajo.

EXTRACCIÓN DE CARACTERÍSTICAS

Ya sea que decida aumentar su conjunto de entrenamiento con imágenes distorsionadas o no, es probable que desee extraer características de las imágenes antes de intentar clasificarlas.

OpenCV ofrece varias técnicas de extracción de características:
Detección de características y descripción

También puede probar técnicas de descomposición de matriz como PCA y NMF para la extracción de características. Estos se implementan en la biblioteca de aprendizaje Python scikit que funciona bastante bien con Python OpenCV.
2.5. Descomposición de señales en componentes (problemas de factorización matricial)

CLASIFICACION DE IMAGEN

Ahora que sus imágenes han sido preprocesadas y convertidas en un número manejable de entradas de intervalo mediante extracción de características, puede usar una técnica de aprendizaje supervisado para clasificar sus imágenes.

OpenCV contiene muchas buenas técnicas de clasificación supervisadas:
Aprendizaje automático
ml. Aprendizaje automático

Así aprende scikit:
1. Aprendizaje supervisado

Si quieres probar técnicas de clasificación de aprendizaje profundo, busca en Theano:
Bienvenido – Documentación de Theano 0.6

Personalmente, soy fanático de las redes neuronales de SAS. Han sido ampliamente utilizados en la industria durante décadas. Son muy escalables, mucho más que MATLAB, robustos y confiables. También son muy caros, pero la mayoría de las grandes instituciones de investigación y corporativas otorgan licencias a SAS. (SAS también es mi empleador …).

Tengo un código vinculado a este documento para construir redes neuronales profundas en SAS: Página en sas.com

EJEMPLO DE CÓDIGO DE PREPROCESO

### IMPORTACIONES ############################################## ######################

importar os
importar cv2
importar csv
importar numpy
matemáticas de importación

### ARGS OPERACIONALES ############################################# ##############

### MODO DEPURACIÓN: IMPRIME EL NÚMERO DE IMÁGENES ESPECIFICADAS POR BEDUG_CUTOFF
DEPURACIÓN = Falso
DEBUG_CUTOFF = 10

### MODO DE TREN
TREN = Verdadero # AGREGA ETIQUETAS A LA PRIMERA COLUMNA
NORMALIZE_ONLY = False # NO AGREGA REGISTROS DISTORTADOS

### IO LOCATION – FILE_IN AND FILE_OUT DEBE ESTAR EN DIR
DIR = ‘C: / Ruta / a / digitsData’
FILE_IN = ‘train.csv’
FILE_OUT = ‘train_augmented.csv’

### NÚMEROS MÁGICOS GLOBALES PARA IMÁGENES … LO SÉ, OK … #########################

INPUT_SIZE = (28, 28) # TAMAÑO DE LA IMAGEN DE ENTRADA, 2-TUPLE
OUT_SIZE = (27, 27) # TAMAÑO DE LA IMAGEN DE SALIDA, 2-TUPLE

NORM_SIZE = (21, 21) # TAMAÑO FINAL DE LA CAJA DE LÍMITES PARA IMÁGENES NORMALIZADAS, 2-TUPLE, <OUT_SIZE
NORM_EXPAND_SIZE = int ((27-NORM_SIZE [0]) / 2)

LARGE_SIZE = (25,25) # TAMAÑO FINAL DE LA CAJA DE LÍMITES PARA IMÁGENES AMPLIADAS, 2-TUPLE, <OUT_SIZE
LARGE_EXPAND_SIZE = int ((27-LARGE_SIZE [0]) / 2)

RAND_PERCENT = .15 # INYECCIÓN DE RUIDO, <1.0
RAND_THRESHOLD = int (OUT_SIZE [0] * OUT_SIZE [0] * RAND_PERCENT)

GRADO = 15 # GRADO DE ROTACIÓN

### MÁS COMPLICADO …

# CONVERTIR UN NÚMERO 1, 7 U OTRO SKINNY EN UN CUADRADO DURANTE LA NORMALIZACIÓN ES DUMB
# EVITE HACERLO, NO VUELVA A AJUSTAR LOS NÚMEROS CUYA DEJÓ MÁS PÍXELES SE ENCUENTRA
# EN UN ÍNDICE> = A SKINNY_THRESHOLD
SKINNY_THRESHOLD = 10

# DIFÍCIL DE VER (Y POR LO TANTO PRUEBA) LA CAJA DE LÍMITES SIN ESTO, 0-255
TO_BLACK_THRESHOLD = 50

### ESCRIBIR IMAGEN PARA GRABAR ########################################### ###########

def write_image_to_record (src, out_csv, row_label = Ninguno):
out = numpy.array (src) .flatten ()
if (row_label! = None): out = numpy.insert (out, 0, row_label)
out_csv.writerow (fuera)

### NORMALIZAR ESCALA ############################################# ###############

def normalize_scale (src, out_size = OUT_SIZE, norm_size = NORM_SIZE, \
norm_expand_size = NORM_EXPAND_SIZE, skinny_threshold = SKINNY_THRESHOLD, \
to_black_threshold = TO_BLACK_THRESHOLD):

src [src <to_black_threshold] = 0
bottom, top = numpy.min (numpy.nonzero (src) [0]), numpy.max (numpy.nonzero (src) [0])
izquierda, derecha = numpy.min (numpy.nonzero (src.T) [0]), numpy.max (numpy.nonzero (src.T) [0])
bounding_box = src [abajo: arriba + 1, izquierda: derecha + 1]
if (left> = skinny_threshold): skinny = True
más: flaco = Falso
si es delgado: devuelve cv2.resize (src, (out_size))
más:
norma = cv2.resize (bounding_box, (norm_size))
return cv2.copyMakeBorder (norm, norm_expand_size, norm_expand_size, norm_expand_size, norm_expand_size, 0)

### RUIDO DE INYECCIÓN ############################################# ##################

def inject_noise (src, out_size = OUT_SIZE, rand_threshold = RAND_THRESHOLD):

ruido = numpy.copy (src) # COPIA PROFUNDA NECESARIA
ruido [numpy.random.randint (out_size [0] -1, tamaño = rand_threshold), numpy.random.randint (out_size [0] -1, tamaño = rand_threshold)] = 0
ruido de retorno

### AMPLIAR ############################################## ######################

def enlarge (src, skinny_threshold = SKINNY_THRESHOLD, input_size = INPUT_SIZE, \
out_size = OUT_SIZE, large_size = LARGE_SIZE, large_expand_size = LARGE_EXPAND_SIZE):

bottom, top = numpy.min (numpy.nonzero (src) [0]), numpy.max (numpy.nonzero (src) [0])
izquierda, derecha = numpy.min (numpy.nonzero (src.T) [0]), numpy.max (numpy.nonzero (src.T) [0])
bounding_box = src [abajo: arriba + 1, izquierda: derecha + 1]
if (left> = skinny_threshold): skinny = True
más: flaco = Falso
si (flaco):
tall_bounding_box = src [bottom-1: top + 2, 0: input_size [0] -1]
return cv2.resize (tall_bounding_box, (out_size))
más:
large = cv2.resize (bounding_box, large_size)
return cv2.copyMakeBorder (large, large_expand_size, large_expand_size, large_expand_size, large_expand_size, 0)

### ROTAR (Y TRADUCIR) ########################################## ###########

def rotate_about_center (src, angle, scale = 1.):

w = src.shape [1]
h = src.shape [0]
rangle = numpy.deg2rad (ángulo) # ANGLE IN RADS
# CALCULAR NUEVAS DIMENSIONES DE IMAGEN
nw = (abs (numpy.sin (rangle) * h) + abs (numpy.cos (rangle) * w)) * scale
nh = (abs (numpy.cos (rangle) * h) + abs (numpy.sin (rangle) * w)) * escala
# OBTENER MATRIZ DE ROTACIÓN
rot_mat = cv2.getRotationMatrix2D ((nw * 0.5, nh * 0.5), ángulo, escala)
# CENTROS ANTIGUOS Y NUEVOS COMBINADOS CON ROTACIÓN
rot_move = numpy.dot (rot_mat, numpy.array ([(nw-w) * 0.5, (nh-h) * 0.5,0]))
# ACTUALIZAR TRADUCCIÓN
rot_mat [0,2] + = rot_move [0]
rot_mat [1,2] + = rot_move [1]
return cv2.warpAffine (src, rot_mat, (int (math.ceil (nw)), int (math.ceil (nh))), flags = cv2.INTER_LANCZOS4)

def main ():

### IO
file_in = open (DIR + ‘/’ + FILE_IN, ‘rb’)
im_in_csv = csv.reader (file_in, dialect = ‘excel’)
file_out = open (DIR + ‘/’ + FILE_OUT, ‘wb’)
im_out_csv = csv.writer (file_out, dialect = ‘excel’)

para i, fila en enumerate (im_in_csv):
si i> 0: # ROW 0 ES SOLO ETIQUETAS

imprimir ‘Procesando imagen’ + str (i) + ‘…’

### GUARDAR ETIQUETA Y LEER LA FILA EN LA IMAGEN
row_array = numpy.asarray (fila)
row_array = row_array.astype (numpy.float32)
row_label = Ninguno
si (TREN):
row_label = row_array [0]
img = numpy.reshape (row_array [1:], (INPUT_SIZE))
más:
img = numpy.reshape (row_array, (INPUT_SIZE))
#if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘raw’ + str (i) + ‘.jpg’, img)

### NORMALIZAR ESCALA
norma = normalizar_escala (img)
write_image_to_record (norma, im_out_csv, row_label)
if (DEPURACIÓN): cv2.imwrite (DIR + ‘/’ + ‘norm’ + str (i) + ‘.jpg’, norm)
if (NORMALIZE_ONLY): continuar

si (TREN):

ruido = ruido_inyectar (norma)
write_image_to_record (noise, im_out_csv, row_label)
if (DEPURACIÓN): cv2.imwrite (DIR + ‘/’ + ‘noise’ + str (i) + ‘.jpg’, noise)

grande = agrandar (norma)
#if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘large’ + str (i) + ‘.jpg’, large)
ruido_grande = agrandar (ruido)
#if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘large_noise’ + str (i) + ‘.jpg’, large_noise)

# rotar + grados
plus = cv2.resize (rotate_about_center (grande, GRADO), OUT_SIZE)
write_image_to_record (plus, im_out_csv, row_label)
if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘rotate_p’ + str (DEGREE) + ‘_’ + str (i) + ‘.jpg’, más)
plus_noise = cv2.resize (rotate_about_center (large_noise, DEGREE), OUT_SIZE)
write_image_to_record (plus_noise, im_out_csv, row_label)
if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘rotate_noise_p’ + str (DEGREE) + ‘_’ + str (i) + ‘.jpg’, plus_noise)

# rotar – grados
menos = cv2.resize (rotate_about_center (grande, -DEGREE), (OUT_SIZE))
write_image_to_record (minus, im_out_csv, row_label)
if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘rotate_m’ + str (DEGREE) + ‘_’ + str (i) + ‘.jpg’, menos)
menos ruido = cv2.resize (rotate_about_center (large_noise, -DEGREE), (OUT_SIZE))
write_image_to_record (minus_noise, im_out_csv, row_label)
if (DEBUG): cv2.imwrite (DIR + ‘/’ + ‘rotate_noise_m’ + str (DEGREE) + ‘_’ + str (i) + ‘.jpg’, minus_noise)

si (DEPURACIÓN):
if (i> = DEBUG_CUTOFF):
descanso

más: im_out_csv.writerow (fila [0: OUT_SIZE [0] * OUT_SIZE [0] +1]) # ESCRIBE ETIQUETAS DE LA FILA

file_in.close ()
file_out.close ()

imprimir ‘Listo’

if __name__ == “__main__”:
principal()

More Interesting

¿Qué tan importante es la optimización de hiperparámetros en los modelos gráficos bayesianos, como la asignación de Dirichlet latente?

¿Cuáles son las ventajas de ReLU sobre softmax en la red neuronal profunda?

Aprendizaje profundo: ¿Por qué no utilizar el entrenamiento sin supervisión para las redes neuronales más tradicionales (superficiales)?

¿Qué cursos debería tomar para especializarse en aprendizaje automático, ciencia de datos e IA como estudiante de MS CS en USC?

Cómo crear mi propia biblioteca de tokenizadores en PNL

¿El aprendizaje automático es un comienzo de invasión de estadísticas?

¿Qué tecnologías existen actualmente para hacer matemáticas en grandes conjuntos de datos?

¿Cuáles son algunos documentos de investigación de inicio sobre búsqueda, aprendizaje automático y recuperación de información?

¿Qué es la agrupación promedio global?

¿Por qué nadie recomienda JavaScript / Node.js como lenguaje para el aprendizaje automático o el análisis de datos?

En problemas de optimización matemática, a menudo se usa la primera derivada. ¿Por qué no el segundo, o derivados de orden superior?

¿Es necesario un MS o PhD en Machine Learning para trabajar en este campo en alguna empresa?

¿Son las preguntas el verdadero punto de partida del análisis de Big Data?

¿Qué áreas del aprendizaje automático son más importantes para los fondos de cobertura y los bancos de inversión (en equipos cuantitativos)?

¿Cuáles son algunos trabajos de investigación basados ​​en ciencia de datos y aprendizaje automático en los que R se utiliza como lenguaje de programación?