Aquí hay una solución alternativa a su problema modelando su pregunta como un 'problema de optimización de ruta'. Aunque es más complicado que la solución simple de binarización y luego ajuste de curva, es más robusto en la práctica.
Desde el nivel más alto, debemos considerar esta imagen como un gráfico, donde
cada píxel de la imagen es un nodo en este gráfico
cada nodo está conectado a otros nodos, conocidos como vecinos, y esta definición de conexión a menudo se refiere a la topología de este gráfico.
cada nodo tiene un peso (característica, costo, energía o como quiera llamarlo), lo que refleja la probabilidad de que este nodo se encuentre en una línea central óptima que estamos buscando.
Mientras podamos modelar esta probabilidad, entonces su problema de encontrar 'las líneas centrales de las franjas' se convierte en el problema de encontrar rutas óptimas locales en el gráfico , que pueden resolverse efectivamente mediante programación dinámica, por ejemplo, el algoritmo de Viterbi.
Aquí hay algunas ventajas de adoptar este enfoque:
todos sus resultados serán continuos (a diferencia del método de umbral que podría dividir una línea central en pedazos)
muchas libertades para construir un gráfico de este tipo, puede seleccionar diferentes características y la topología del gráfico.
sus resultados son óptimos en el sentido de optimizaciones de ruta
su solución será más robusta contra el ruido, porque mientras el ruido se distribuya por igual entre todos los píxeles, esas rutas óptimas permanecerán estables.
Aquí hay una breve demostración de la idea anterior. Como no utilizo ningún conocimiento previo para especificar qué son posibles nodos iniciales y finales, simplemente decodifico wrt cada posible nodo inicial.
Para las terminaciones difusas, se debe al hecho de que estamos buscando rutas óptimas para todos los nodos finales posibles. Como resultado, aunque para algunos nodos ubicados en áreas oscuras, la ruta resaltada sigue siendo la óptima local.
Para el camino difuso, puede suavizarlo después de encontrarlo o usar algunas características suavizadas en lugar de intensidad bruta.
Es posible restaurar rutas parciales cambiando nodos iniciales y finales.
No será difícil podar estas rutas óptimas locales no deseadas. Debido a que tenemos las probabilidades de todas las rutas después de la decodificación de viterbi, y puede usar varios conocimientos previos (por ejemplo, vemos que es cierto que solo necesitamos una ruta óptima para aquellos que comparten la misma fuente).
Para más detalles, puede consultar el documento.
Wu, Y.; Zha, S.; Cao, H.; Liu, D., & Natarajan, P. (2014, February). A Markov Chain Line Segmentation Method for Text Recognition. In IS&T/SPIE 26th Annual Symposium on Electronic Imaging (DRR), pp. 90210C-90210C.
Aquí hay un pequeño fragmento de código de Python que se usa para hacer el gráfico anterior.
import cv2
import numpy as np
from matplotlib import pyplot
# define your image path
image_path = ;
# read in an image
img = cv2.imread( image_path, 0 );
rgb = cv2.imread( image_path, -1 );
# some feature to reflect how likely a node is in an optimal path
img = cv2.equalizeHist( img ); # equalization
img = img - img.mean(); # substract DC
img_pmax = img.max(); # get brightest intensity
img_nmin = img.min(); # get darkest intensity
# express our preknowledge
img[ img > 0 ] *= +1.0 / img_pmax;
img[ img = 1 :
prev_idx = vt_path[ -1 ].astype('int');
vt_path.append( path_buffer[ prev_idx, time ] );
time -= 1;
vt_path.reverse();
vt_path = np.asarray( vt_path ).T;
# plot found optimal paths for every 7 of them
pyplot.imshow( rgb, 'jet' ),
for row in range( 0, h, 7 ) :
pyplot.hold(True), pyplot.plot( vt_path[row,:], c=np.random.rand(3,1), lw = 2 );
pyplot.xlim( ( 0, w ) );
pyplot.ylim( ( h, 0 ) );