Je veux diviser automatiquement une image d'un texte manuscrit ancien par lignes (et par mots à l'avenir).
La première partie évidente est le prétraitement de l'image...
J'utilise simplement une numérisation simple (basée sur la luminosité du pixel). Après cela, je stocke les données dans un tableau bidimensionnel.
La prochaine étape évidente est l'analyse du tableau binaire.
-
Mon premier algorithme était assez simple : s'il y a plus de pixels noirs dans une rangée du tableau que la moyenne quadratique des pixels noirs de l'échantillon. Maximum et Minimum alors cette ligne fait partie de la ligne.
Après avoir formé la liste des lignes, j'ai coupé les lignes avec hauteur qui est inférieur à la moyenne. Finalement, il s'agit d'une sorte de régression linéaire, qui tente de minimiser la différence entre les lignes vides et les lignes de texte. (J'ai supposé que ce fait)
-
Ma deuxième tentative - J'ai essayé d'utiliser GA avec plusieurs fonctions de fitness. Le chromosome contenait 3 valeurs - xo, x1, x2. xo [-1;0] x1 [0;0.5] x2 [0;0.5]
Fonction, qui détermine l'identité la ligne à la ligne est (xo + 1 x1 + 2 x2) > 0 où 1 est la somme mise à l'échelle des pixels noirs de la ligne, 2 est la valeur médiane des intervalles entre les pixels noirs extrêmes de la ligne. (a1,a2 [0,1]) Une autre fonction, que j'ai essayée est (x1 < 1 OU x2 > 2) et (1/xo + [a1 x1] / [a2 x2] ) > 0 La dernière fonction est la plus efficace. La fonction de fitness est (1 / (HeigthRange + SpacesRange)
Où l'étendue est la différence entre le maximum et le minimum. Elle représente l'homogénéité du texte. L'optimum global de cette fonction - la manière la plus douce de diviser l'image en lignes.
J'utilise C# avec mon AG auto-codé (classique, avec croisement à 2 points, chromosomes à code gris, population maximale de 40, taux de mutation de 0,05).
Maintenant, je suis à court d'idées pour diviser cette image en lignes avec une précision de ~100%.
Quel est l'algorithme efficace pour faire cela ?
UPDATE : BMP original (1.3 MB)
UPDATE2 : Amélioration des résultats sur ce texte à 100%.
Comment je l'ai fait :
- correction d'un bug mineur dans le comptage des plages
- modification de la fonction d'aptitude en 1/(distancesRange+1)*(hauteursRange+1))
- fonction de classification minimisée à (1/xo + x2/gamme) > 0 (les points dans la rangée n'affectent pas la classification) (c.-à-d. optimisation des données d'entrée et optimisation plus explicite de la fonction de fitness)
Problème :
GA n'a étonnamment pas reconnu cette ligne. J'ai regardé les données de débogage de la fonction "find rages" et j'ai constaté qu'il y avait trop de bruit à l'endroit "non reconnu". Le code de la fonction est ci-dessous :
public double[] Ranges()
{
var ranges = new double[_original.Height];
for (int y = 0; y < _original.Height; y++ )
{
ranges[y] = 0;
var dx = new List<int>();
int last = 0;
int x = 0;
while (last == 0 && x<_original.Width)
{
if (_bit[x, y])
last = x;
x++;
}
if (last == 0)
{
ranges[y] = 0;
continue;
}
for (x = last; x<_original.Width; x++)
{
if (!_bit[x, y]) continue;
if (last != x - 1)
{
dx.Add((x-last)+1);
}
last = x;
}
if (dx.Count > 2)
{
dx.Sort();
ranges[y] = dx[dx.Count / 2];
//ranges[y] = dx.Average();
}
else
ranges[y] = 0;
}
var maximum = ranges.Max();
for (int i = 0; i < ranges.Length; i++)
{
if (Math.Abs(ranges[i] - 0) < 0.9)
ranges[i] = maximum;
}
return ranges;
}
J'utilise quelques astuces dans ce code. La raison principale - je veux minimiser l'écart entre les pixels noirs les plus proches, mais s'il n'y a pas de pixels, la valeur devient '0', et il devient impossible de résoudre ce problème en trouvant des optimas. La deuxième raison - ce code change trop fréquemment. Je vais essayer de changer complètement ce code, mais je n'ai aucune idée de comment le faire.
Q :
- S'il existe une fonction de fitness plus efficace ?
- Comment trouver une fonction de détermination plus polyvalente ?
1 votes
Je sais que SIFT a été utilisé avec succès dans la segmentation de textes manuscrits, mais je n'ai pas d'expérience pratique.
1 votes
Je suis un novice en matière d'algorithmes, mais je crois avoir trouvé des sites qui traitaient de l'utilisation de modèles de Markov cachés pour la reconnaissance de texte. S'il peut reconnaître du texte, il peut peut-être aussi reconnaître les espaces/nouveaux mots...
1 votes
J'ai trouvé ce lien avec un certain code il ne fait pas exactement ce que vous voulez mais peut vous donner une idée et ensuite vous pouvez le modifier pour vos besoins. codeproject.com/Articles/69647/Hidden-Markov-Models-in-C
3 votes
Veuillez poster une image du texte clair (sans vos marques de traitement) pour que nous puissions jouer un peu.
0 votes
De plus, je ne suis pas sûr du problème de votre deuxième algorithme, outre le fait que la dernière ligne courte n'est pas reconnue
0 votes
Mise à jour du message avec le lien vers l'image originale. Le principal problème de l'AG est de trouver une bonne fonction de fitness et une fonction de déclenchement, qui détermine l'identité de la ligne à la ligne.
0 votes
Je pense que ce n'est pas le bon endroit pour poster cette question. La reconnaissance de l'écriture manuscrite est un vaste sujet de recherche avec de nombreuses publications. Une simple recherche dans scholar.google.com vous aurait aidé bien au-delà de votre imagination. Vous n'avez pas besoin de réinventer la roue une fois de plus.
0 votes
@inf.ig.sh Je n'ai pas besoin de reconnaître ce texte. De plus, je ne peux accéder à aucune des publications données par scholar.google.com.
1 votes
@Ernado Une partie importante de la reconnaissance de texte est la segmentation du texte. Si vous cliquez sur "versions", vous découvrirez qu'environ 25-30% des publications peuvent être téléchargées en pdf.
0 votes
@inf.ig.sh je l'ai enfin trouvé, merci.
0 votes
GA ne sera probablement jamais performant à 100%. Vos résultats semblent plutôt bons.
0 votes
Mise à jour du message principal. Je pense que GA peut être plus performant.
0 votes
Cette question bénéficierait de la segmentation d'image mais je n'ai pas la prétention de savoir quelle autre étiquette il faut larguer pour faire de la place.
0 votes
Le Méta-Post des 10 millions de questions m'a conduit ici. Réponse géniale. +1.