Au cours de l'échange de piles TeX, nous avons discuté de la façon de détecter les "rivières" dans les paragraphes de cette question .
Dans ce contexte, les rivières sont des bandes d'espaces blancs résultant d'un alignement accidentel d'espaces inter-mots dans le texte. Comme cela peut être assez dérangeant pour un lecteur, les mauvaises rivières sont considérées comme un symptôme d'une mauvaise typographie. Celui-ci est un exemple de texte avec des rivières, où deux rivières coulent en diagonale.
Il est intéressant de détecter ces rivières automatiquement, afin de les éviter (probablement par édition manuelle du texte). Raphink fait quelques progrès au niveau de TeX (qui ne connaît que les positions des glyphes et les cadres de sélection), mais je suis convaincu que le meilleur moyen de détecter les rivières est de traiter certaines images (les formes de glyphes étant très importantes et non disponibles pour TeX) . J'ai essayé diverses méthodes pour extraire les rivières de l'image ci-dessus, mais ma simple idée d'appliquer une petite quantité de flou ellipsoïdal ne semble pas suffisante. J'ai aussi essayé du radonLe filtrage basé sur la transformation de Hough, mais je n’ai rien obtenu non plus. Les rivières sont très visibles pour les circuits de détection des caractéristiques de l'œil humain / de la rétine / du cerveau et je penserais que cela pourrait se traduire par une sorte d'opération de filtrage, mais je ne parviens pas à le faire fonctionner. Des idées?
Pour être précis, je recherche une opération qui détectera les 2 rivières dans l’image ci-dessus, mais n’aura pas trop d’autres détections de faux positifs.
EDIT: endolith m'a demandé pourquoi je poursuivais une approche basée sur le traitement d'images, étant donné que dans TeX, nous avons accès aux positions des glyphes, aux espacements, etc. Ma raison de faire les choses dans l'autre sens est que la formedes glyphes peut avoir une incidence sur la perception d’une rivière et, au niveau du texte, il est très difficile d’envisager cette forme (qui dépend de la police, de la ligature, etc.). Pour un exemple de l'importance de la forme des glyphes, considérons les deux exemples suivants. La différence est que j'ai remplacé quelques glyphes par d'autres de la même largeur, de sorte qu'une analyse basée sur le texte prendrait en compte: eux aussi bien / mauvais. Notez cependant que les rivières dans le premier exemple sont bien pires que dans le second.
la source
ImageLines[]
de Mathematica, avec et sans prétraitement. J'imagine qu'il s'agit techniquement d'une transformation de Hough plutôt que de radon. Cela ne me surprendra pas si le prétraitement approprié (je n'ai pas essayé le filtre de dilatation suggéré par le datagraphe) et / ou les réglages de paramètres peuvent réussir ce travail.Réponses:
J'y ai réfléchi un peu plus et je pense que ce qui suit devrait être assez stable. Notez que je me suis limité aux opérations morphologiques, car celles-ci devraient être disponibles dans toutes les bibliothèques de traitement d'image standard.
(1) Ouvrir une image avec un masque nPix par 1, nPix correspondant à la distance verticale entre les lettres.
(2) Ouvrez l’image avec un masque 1-sur-mPix pour éliminer tout ce qui est trop étroit pour être une rivière.
(3) Supprimez les "rivières et les lacs" horizontaux dus à l'espace entre les paragraphes ou à l'indentation. Pour cela, nous supprimons toutes les lignes qui sont toutes vraies et les ouvrons avec le masque nPix par 1 qui, à notre connaissance, n’affectera pas les rivières que nous avons trouvées précédemment.
Pour supprimer les lacs, nous pouvons utiliser un masque d’ouverture légèrement plus grand que nPix-by-nPix.
À ce stade, nous pouvons également éliminer tout ce qui est trop petit pour être une véritable rivière, c’est-à-dire tout ce qui couvre moins de surface que (nPix + 2) * (mPix + 2) * 4 (cela nous donnera environ 3 lignes). Le +2 est là parce que nous savons que tous les objets ont au moins nPix en hauteur et mPix en largeur, et nous voulons aller un peu au-dessus de cela.
(4) Si nous nous intéressons non seulement à la longueur, mais également à la largeur de la rivière, nous pouvons combiner la transformation de la distance avec le squelette.
(les couleurs correspondent à la largeur de la rivière (bien que la barre de couleur soit un facteur 2)
Vous pouvez maintenant obtenir la longueur approximative des rivières en comptant le nombre de pixels de chaque composant connecté et la largeur moyenne en faisant la moyenne de leurs valeurs de pixels.
Voici la même analyse appliquée à la deuxième image "pas de rivière":
la source
Dans Mathematica, en utilisant l'érosion et la transformation de Hough:
Editer répondre au commentaire de l'assistant
Si vous voulez vous débarrasser des lignes horizontales, faites plutôt quelque chose comme ceci (probablement quelqu'un pourrait le rendre plus simple):
la source
lines = ImageLines[ImageResize[#, {300, 300}], .6, "Segmented" -> True] & /@ i1;
. Cela dit, pour ce problème, une approche morphologique semble plus robuste.Hmmm ... Je suppose que la transformation de Radon n'est pas si facile à extraire. (La transformation du radon fait essentiellement pivoter l'image tout en "regardant à travers". C'est le principe qui sous-tend les balayages CAT.) La transformation de votre image produit ce sinogramme, les "rivières" formant des pics lumineux encerclés:
Celui à une rotation de 70 degrés peut être vu assez clairement comme le pic à gauche de cette représentation d'une coupe sur l'axe horizontal:
Surtout si le texte était d'abord gaussien flou:
Mais je ne sais pas comment extraire de manière fiable ces pics du reste du bruit. Les extrémités supérieure et inférieure lumineuses du sinogramme représentent les "rivières" situées entre des lignes de texte horizontales, qui ne vous intéressent évidemment pas. Peut-être qu'une fonction de pondération par rapport à un angle accentue davantage les lignes verticales et minimise les lignes horizontales?
Une simple fonction de pondération en cosinus fonctionne bien sur cette image:
trouver le fleuve vertical à 90 degrés, ce qui correspond aux maxima globaux du sinogramme:
et sur cette image, trouver celle à 104 degrés, bien que le flou le rende plus précis:
(La
radon()
fonction de SciPy est plutôt idiote , ou je mapperais ce sommet sur l'image d'origine sous la forme d'une ligne traversant le milieu de la rivière.)Mais il ne trouve aucun des deux pics principaux dans le sinogramme pour votre image, après avoir brouillé et pondéré:
Ils sont là, mais ils sont dépassés par les éléments proches du sommet de la fonction de pondération. Avec une pondération et des ajustements appropriés, cette méthode pourrait probablement fonctionner, mais je ne suis pas sûre de ce que sont les ajustements appropriés. Cela dépend probablement aussi des propriétés des scans de la page. Peut-être que la pondération doit être dérivée de l'énergie globale de la tranche ou de quelque chose comme une normalisation.
la source
J'ai formé un classifieur discriminant sur les pixels à l'aide de fonctions dérivées (jusqu'au 2e ordre) à différentes échelles.
Mes étiquettes:
Prédiction sur l'image d'entraînement:
Prédiction sur les deux autres images:
Je suppose que cela semble prometteur et pourrait donner des résultats utilisables avec davantage de données de formation et peut-être des fonctionnalités plus intelligentes. Par contre, il ne m'a fallu que quelques minutes pour obtenir ces résultats. Vous pouvez reproduire les résultats vous-même à l'aide du logiciel open source ilastik . [Avertissement: je suis l'un des principaux développeurs.]
la source
(Désolé, cet article ne vient pas avec des démonstrations géniales.)
Si vous souhaitez utiliser les informations que TeX possède déjà (lettres et positions), vous pouvez classer manuellement les lettres et les paires de lettres comme "en pente" dans un sens ou dans un autre. Par exemple, "w" a des pentes de coin SW et SE, le combo "al" a une pente de coin NO, "k" a une pente de coin NE. (N'oubliez pas la ponctuation - une citation suivie d'une lettre qui remplit la moitié inférieure de la boîte à glyphes établit une belle pente; la citation suivie de q est particulièrement forte.)
Ensuite, recherchez les occurrences de pentes correspondantes sur les côtés opposés d'un espace - "w al" pour une rivière d'ouest en nord-est ou "k T" pour une rivière d'ouest en nord-est. Lorsque vous en trouvez un sur une ligne, voyez si un événement similaire se produit, décalé de manière appropriée vers la gauche ou la droite, sur les lignes ci-dessus / ci-dessous; quand vous en trouvez une course, il y a probablement une rivière.
Aussi, évidemment, il suffit de chercher des espaces empilés presque verticalement, pour les rivières verticales de plaine.
Vous pouvez obtenir un peu plus sophistiqué en mesurant la "force" de la pente: quelle part de la zone d’avancée est "vide" en raison de la pente et contribue ainsi à la largeur de la rivière. "w" est assez petit, car il ne dispose que d'un petit coin de sa boîte d'avance pour contribuer à la rivière, mais "V" est très fort. "b" est légèrement plus fort que "k"; la courbe plus douce donne un bord de rivière plus visuellement continu, ce qui le rend plus fort et plus large visuellement.
la source