6
votes

Séparer l'image de texte en images de personnage composant

Je voudrais séparer une image de texte en caractères de composants, également comme des images. Par exemple, en utilisant l'échantillon ci-dessous, je vous retrouverais avec 14 images.

Je vais seulement utiliser du texte sur une seule ligne. La hauteur de Y est donc sans importance - ce que je dois trouver est le début et la fin de chaque lettre et de la récolte à ces coordonnées. De cette façon, j'éviterais également des problèmes de 'i', "j", etc.

Je suis nouveau dans le traitement de l'image, et je ne sais pas comment y aller. Une forme de détection de bord? Existe-t-il un moyen de déterminer les régions contiguës de couleur unie? Toute aide est excellente.

essayer d'améliorer mes compétences en python et de la familiarité avec certaines des nombreuses bibliothèques disponibles, j'utilise donc le Bibliothèque d'imagerie Python (PIL) , mais j'ai aussi consulté OpenCV.


Image d'échantillon:

ceci est un texte


0 commentaires

6 Réponses :


6
votes

Ce n'est pas une tâche facile, surtout si l'arrière-plan n'est pas uniforme. Si ce que vous avez est une image déjà binaire comme l'exemple, il est légèrement plus simple.

Vous pouvez commencer à appliquer un algorithme de seuil si votre image n'est pas binaire (le seuil d'adaptation d'Otsu fonctionne bien)

Après avoir utilisé un algorithme d'étiquetage afin d'identifier chaque «pixels de l'île» qui forme vos formes (chaque caractère dans ce cas).

Le problème se pose lorsque vous avez du bruit. Formes qui étaient étiquetées mais ne sont pas de votre intérêt. Dans ce cas, vous pouvez utiliser une certaine heuristique pour déterminer lorsqu'une forme est un caractère ou non (vous pouvez utiliser une zone normalisée, la position de l'objet si votre texte est dans un lieu bien défini, etc.). Si cela ne suffit pas, vous devrez gérer un personnel plus complexe comme des algorithmes d'extraction de forme de forme et une sorte d'algorithme de reconnaissance de modèle, comme des percepteurs multicouches.

Pour terminer, cela semble être une tâche facile, mais en fonction de la qualité de votre image, cela pourrait devenir plus difficile. Les algorithmes cités ici peuvent facilement être trouvés sur Internet ou également implémenté dans certaines bibliothèques telles que OpenCV.

Plus d'aide, demandez simplement, si je peux aider bien sûr;)


1 commentaires

Merci pour votre réponse! À ce stade, je ne suis intéressé que par le traitement d'images simples comme l'échantillon que j'ai fourni, texte noir sur le blanc solide. Les autres considérations que je pourrais construire plus tard, alors merci pour les conseils. Un algorithme d'étiquetage, alors? Un rapide Google obtient moi cvblobslib de la bibliothèque OpenCV, qui semble pouvoir faire le travail de trouver les formes. Je ne sais pas comment allez-y les sauver, mais je vais y aller.



1
votes

J'ai joué avec OCROPUS Récemment, une analyse de texte open source et outil de prétraitement OCR. Dans le cadre de son flux de travail, il crée également les images que vous souhaitez. Peut-être que cela vous aide, bien qu'aucune magie Python n'est impliquée.


0 commentaires

1
votes

Le problème que vous avez posé est vraiment difficile - il a fallu un certain temps certains des meilleurs chercheurs de traitement d'image au monde à résoudre. La solution est une partie majeure du DJVU Tableau d'outils de compression d'image et d'affichage: leur première étape de compression d'un document est de identifier le premier plan et le diviser en caractères. Ils utilisent ensuite les informations pour aider à la compression car l'image d'une minuscule 'E' est beaucoup comme une autre - le document compressé doit ne contenir que les différences. Vous trouverez des liens vers un tas de documents techniques à http://djvu.org/resources/ ; Un bon endroit pour démarrer est avec Compression de l'image de haute qualité avec DJVU .

Un bon nombre des outils de la suite DJVU ont été ouverts sous le titre Djvulibre ; Malheureusement, je n'ai pas pu comprendre comment tirer le premier plan (ou les caractères individuels) en utilisant les outils de ligne de commande existants. Je serais très intéressé de voir cela fait.


0 commentaires

2
votes

Vous pouvez commencer par un algorithme d'analyse de composants connectés simple (CCA), qui peut être implémenté de manière assez efficace avec un algorithme Scanline (vous gardez simplement une trace des régions fusionnées et de la relabel à la fin). Cela vous donnerait des «blobs» numérotés séparément pour chaque région continue, ce qui fonctionnerait pour la plupart des lettres (mais pas toutes). Ensuite, vous pouvez simplement prendre la boîte de sélection de chaque blob connecté et cela vous donnera le contour pour chacun. Vous pouvez même maintenir la boîte de sélection lorsque vous appliquez la CCA pour l'efficacité.

Donc, dans votre exemple, le premier mot de la gauche après la CCA entraînerait quelque chose comme: P>

1111111  2         3
   1     2
   1     2 4444    5  666
   1     22    4   5 6
   1     2     4   5  666
   1     2     4   5     6
   1     2     4   5  666


0 commentaires

2
votes

euh, ceci est en fait très facile pour l'échantillon que vous avez fourni: xxx

(Incidemment, cela fonctionne également pour diviser un paragraphe dans des lignes.)
Si les lettres se chevauchent ou partagent des colonnes, il obtient un peu plus difficile intéressant.

EDIT:

@andres, non, ça marche bien pour 'u ', vous devez regarder tout de chaque colonne xxx


1 commentaires

Il y a un problème avec cette approche. Les étapes «vont à droite jusqu'à ce qu'aucun noir, la fin du caractère» ne soit pas vrai. Si vous traitez «U» ou même le caractère «H», la fin du noir ne signifie pas fin de caractère car ils forment deux colonnes de pixels avec espace blanc entre les deux.



6
votes

Je sais que je suis quelques années de retard :-) Mais vous pouvez faire ce genre de chose avec ImageMagick, tout à fait à la ligne de commande sans rien compiler, car elle a connecté une analyse de composants intégrée:

Voici une façon de le faire comme ça: xxx

Le résultat ressemble à ceci:

 Entrez la description de l'image ici

Premièrement, je seules votre image à 50% de manière à ce qu'il n'y ait que des noirs et des blancs pure, pas de gradations tonales. Ensuite, je dis imagemagick pour produire des détails sur les zones de liaison qu'il trouve et que je ne suis pas intéressé par des objets inférieurs à 10 pixels de la superficie totale. Je laisse ensuite les pixels d'être connectés à 8, c'est-à-dire à leurs voisins diagonaux (NE, SE, NW, SW) ainsi que leurs voisins à gauche et au-dessous des voisins. Enfin, je parsais la sortie de la boîte de sélection avec awk pour dessiner des lignes rouges autour des zones de liaison.

La sortie de la commande initiale que je pars avec awk ressemble à ceci: xxx

et le awk tourne dans ce xxx


6 commentaires

@Schell, je reçois cette erreur lors de l'exécution de votre script. Convertir: Aucune image définie 'word.png' @ error / convert.c / convertimagecommand / 3275. Pouvez-vous aider?


@Shreeshan Comment l'avez-vous dirigé? Quelle image avez-vous utilisée? Quelle version d'imagemagick utilisez-vous? Dans quel système d'exploitation êtes-vous? Essayez d'ajouter `-xv` à la fin de la première ligne.


ImageMagick Version - 7.0.7-38, Image - JPG / PNG, OS - MacOS. Ajouter -xv n'a pas aidé. aucune erreur définie d'images persiste toujours


Comment l'avez-vous dirigé?


L'a enregistré dans un fichier .sh et ran sh filename.sh


Vous devez transmettre le nom de votre image comme premier paramètre. Vous ne devez pas non plus exécuter bash scripts avec sh car sh n'est pas bash .