Voici encore une solution alternative à votre problème en modélisant votre question comme un «problème d'optimisation de chemin». Bien qu'elle soit plus compliquée que la simple solution de binarisation et d'ajustement de courbe, elle est plus robuste dans la pratique.
Du niveau très élevé, nous devons considérer cette image comme un graphique, où
chaque pixel d'image est un nœud sur ce graphique
chaque nœud est connecté à d'autres nœuds, appelés voisins, et cette définition de connexion est souvent référée à la topologie de ce graphique.
chaque nœud a un poids (fonctionnalité, coût, énergie, ou ce que vous voulez appeler), reflétant la probabilité que ce nœud soit dans une ligne centrale optimale que nous recherchons.
Tant que nous pouvons modéliser cette probabilité, votre problème de trouver `` les lignes centrales des franges '' devient le problème de trouver des chemins locaux optimaux sur le graphique , qui peuvent être résolus efficacement par programmation dynamique, par exemple l'algorithme de Viterbi.
Voici quelques avantages d'adopter cette approche:
tous vos résultats seront continus (contrairement à la méthode de seuil qui pourrait casser une ligne centrale en morceaux)
beaucoup de libertés pour construire un tel graphique, vous pouvez sélectionner différentes fonctionnalités et la topologie du graphique.
vos résultats sont optimaux dans le sens d'optimisations de chemin
votre solution sera plus robuste contre le bruit, car tant que le bruit est réparti également entre tous les pixels, ces chemins optimaux restent stables.
Voici une courte démonstration de l'idée ci-dessus. Comme je n'utilise aucune connaissance préalable pour spécifier les nœuds de début et de fin possibles, je décode simplement wrt chaque nœud de départ possible.
Pour les terminaisons floues, cela est dû au fait que nous recherchons des chemins optimaux pour tous les nœuds de terminaison possibles. Par conséquent, bien que pour certains nœuds situés dans des zones sombres, le chemin en surbrillance reste son optimal local.
Pour le chemin flou, vous pouvez soit le lisser après l'avoir trouvé, soit utiliser des fonctions lissées au lieu de l'intensité brute.
Il est possible de restaurer des chemins partiels en modifiant les nœuds de début et de fin.
Il ne sera pas difficile d'élaguer ces chemins optimaux locaux indésirables. Parce que nous avons les probabilités de tous les chemins après le décodage viterbi, et vous pouvez utiliser diverses connaissances antérieures (par exemple, nous voyons qu'il est vrai que nous n'avons besoin que d'un chemin optimal pour ceux qui partagent la même source.)
Pour plus de détails, vous pouvez vous référer au document.
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.
Voici un court morceau de code python utilisé pour créer le graphique ci-dessus.
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 ) );