9
votes

Extraire des mots dans des rectangles du texte

J'ai du mal à extraire des mots rapides et efficaces qui sont dans des rectangles d'un bufferedimage.
Par exemple, j'ai la page suivante: (Modifier!) L'image est numérisée, elle peut donc contenir du bruit, une biaiser et une distorsion. de
Entrez la description de l'image ici



Comment puis-je extraire les images suivantes sans le rectangle: (Modifier!) Je peux utiliser OpenCV ou toute autre bibliothèque, mais je suis absolument nouveau pour les techniques de traitement d'images avancées. Entrez la description de l'image ici

EDIT < P> J'ai utilisé la méthode suggérée par karlphillip Ici et ça marche décent.
Voici le code: xxx

}


et la classe rectangle xxx

Exemple de résultat:

Entrez la description de l'image ici Entrez la description de l'image ici de


... cependant, cela ne fonctionne pas si bien pour les plus petites images: Entrez la description de l'image ici  Entrez la description de l'image ici

peut-être que certaines améliorations peuvent être suggérées? Ou comment rendre l'algorithme plus rapidement au cas où j'ai un lot d'images pour traiter?


6 commentaires

Pouvez-vous donner plus d'informations comme si vous souhaitez utiliser OPENCV? Avez-vous les positions rectangiles? Qu'avez-vous encore essayé?


Je n'ai pas essayé d'utiliser Opencv, mais ça va, toutes les bibliothèques sont les bienvenues, aussi longtemps que c'est rapide ... J'ai essayé d'identifier des formes de type rectangle dans l'image..mais qui n'ont pas très bien fonctionné. Non, je n'ai pas les positions rectangiles.


Est-ce l'image d'entrée exacte (c'est-à-dire que cela peut servir de cas de test)? Dans quelle mesure votre tentative a-t-elle été approchée de ne pas "travailler très bien"?


Oui, cela peut être utilisé comme cas de test. Mon approche n'est pas efficace ... j'ai pensé à segmenter l'image par "espaces": dans ce cas exacte, je voudrais obtenir chaque image contenant un personnage, à l'exception de ceux des rectangles, je voudrais obtenir tout le rectangle. Après cela, j'aurais besoin de Pour vérifier chaque image si l'image est un caractère ou un rectangle .. Pour les rectangles, je devrais extraire le texte ..


Pls-Send-Me-The-Code Les questions ne sont pas bien reçues par la Communauté et mettent une prime à ce sujet une erreur encore plus grande.


@karlphillip Je comprends, merci pour le conseil .. Je voulais changer le message de Bounty avant, mais je pense que ce n'est pas possible :)


5 Réponses :


2
votes

Tout d'abord, j'espère que vous êtes déjà au courant du traitement de l'image car vous aurez besoin d'une partie de cela pour continuer :)

Voici un lien sur les moyens de le faire: https: // dsp .stackexchange.com / Questions / 3324 / Comment-rectangle-rectangles-rectangles

Mais pour résumer la méthode la plus utilisée consisterait à utiliser un canny (Détecteur des bords) et à appliquer Hough afin de détecter la ligne droite et de considérer le Résultats trouvez le rectangle. En fait, Hough est généralement utilisé pour détecter la ligne droite et un rectangle ne fait que 4 lignes droites avec un angle de 90 ° entre chacun d'eux. Ainsi, en utilisant tout cela, vous pourrez peut-être améliorer vos recherches;)

J'espère que cela aidera;)


0 commentaires

3
votes

Je ne sais pas si des compétences "réelles" de traitement d'images sont nécessaires.

Une fois que vous avez commencé à résoudre ce problème avec OpenCV, des filtres SOBel / Canny, des détections de bord et des transformations de Hough, il commence à devenir plutôt impliqué. Mais peut-être tout cela n'est pas nécessaire ici.

Tout dépend de la manière dont "prévisible" l'entrée est. C'est pourquoi j'ai demandé aux commentaires si l'image peut servir de cas de test. Si les rectangles sont toujours alignés sur l'axe et n'ont pas de bruit, de distorsions et d'interruptions, cela peut être résolu avec des boucles triviales et des comparaisons de pixels.

Donc, si vous avez des images d'entrée potentiellement bruyantes ou déformées, alors ... bonne chance, vous devrez peut-être acquérir de nombreuses compétences en matière de traitement d'images. Si l'image n'est pas déformée ou bruyante, une solution comme celle-ci pourrait être suffisante: xxx


2 commentaires

Oui c'est aussi vrai :)


Cela fonctionne très bien sur ce cas de test. Mais d'accord, je ne pensais pas à venir .. Si l'image sera une copie numérisée, alors cela va inévitablement avoir des distorsions et du bruit ... donc j'ai probablement besoin d'une autre approche ... merci!



3
votes

Voici un algorithme que j'ai démontré sur un Projet similaire à l'aide de OPENCV:


3 commentaires

Merci pour les références, cela a beaucoup aidé! Pouvez-vous s'il vous plaît jeter un oeil au code et le résultat après la modification: puis-je apporter des améliorations pour que la méthode soit plus précise? (Si vous examinez le premier résultat, les carrés sont un peu recadrés) et peut-être le faire fonctionner pour des images plus petites?


Et je ne comprends pas pourquoi cela ne fonctionne pas pour l'image dans la question originale .. Je reçois ce résultat Image


@Iulianrosca check dhanushka réponse!



7
votes

J'ai fait le programme suivant en C ++ en utilisant OpenCV (je ne connais pas Java + OpenCV). J'ai inclus la sortie pour les deux échantillons d'images que vous avez fournies. Vous devrez peut-être régler les seuils dans la section de filtrage de contour pour d'autres images.

#include "stdafx.h"

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    // load image as grayscale
    Mat im = imread(INPUT_FILE, CV_LOAD_IMAGE_GRAYSCALE);

    Mat morph;
    // morphological closing with a column filter : retain only large vertical edges
    Mat morphKernelV = getStructuringElement(MORPH_RECT, Size(1, 7));
    morphologyEx(im, morph, MORPH_CLOSE, morphKernelV);

    Mat bwV;
    // binarize: will contain only large vertical edges
    threshold(morph, bwV, 0, 255.0, CV_THRESH_BINARY | CV_THRESH_OTSU);

    // morphological closing with a row filter : retain only large horizontal edges
    Mat morphKernelH = getStructuringElement(MORPH_RECT, Size(7, 1));
    morphologyEx(im, morph, MORPH_CLOSE, morphKernelH);

    Mat bwH;
    // binarize: will contain only large horizontal edges
    threshold(morph, bwH, 0, 255.0, CV_THRESH_BINARY | CV_THRESH_OTSU);

    // combine the virtical and horizontal edges
    Mat bw = bwV & bwH;
    threshold(bw, bw, 128.0, 255.0, CV_THRESH_BINARY_INV);

    // just for illustration
    Mat rgb;
    cvtColor(im, rgb, CV_GRAY2BGR);

    // find contours
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(bw, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
    // filter contours by area to obtain boxes
    double areaThL = bw.rows * .04 * bw.cols * .06;
    double areaThH = bw.rows * .7 * bw.cols * .7;
    double area = 0;
    for(int idx = 0; idx >= 0; idx = hierarchy[idx][0])
    {
        area = contourArea(contours[idx]); 
        if (area > areaThL && area < areaThH)
        {
            drawContours(rgb, contours, idx, Scalar(0, 0, 255), 2, 8, hierarchy);
            // take bounding rectangle. better to use filled countour as a mask
            // to extract the rectangle because then you won't get any stray elements
            Rect rect = boundingRect(contours[idx]);
            cout << "rect: (" << rect.x << ", " << rect.y << ") " << rect.width << " x " << rect.height << endl;
            Mat imRect(im, rect);
        }
    }

    return 0;
}


3 commentaires

+1 C'est une très bonne réponse. Il fournit un code pour résoudre le problème, une explication de ce qu'elle fait et des images résultantes. Bon travail!


Très bonne réponse. Pouvez-vous poster le résultat pour ces images: 1-Image , 2-image . J'ai mis en place votre approche, ce qui sont les résultats -> 1-image et 2-Image


Mes résultats ressemblent à la même chose que les vôtres. Je n'ai pas cible la solution pour une image complexe comme la seconde. Si vous examinez les images de résultat intermédiaire, vous remarquerez que le seuil d'Otsu a laissé la boîte autour du mot, et si vous observez l'histogramme d'image grise, vous verrez qu'il n'est pas bimodal, alors le seuil d'tsu ne ferait pas bien. Même si vous obtenez le seuil de droite, vous auriez toujours besoin d'un mécanisme pour filtrer les faux hits. Une approche de segmentation de mots ferait mieux pour des images complexes.



1
votes

Une solution possible consiste à effectuer une analyse des composants connectés après la binarisation à l'aide de la méthode adaptative. Après cela, calculez la largeur médiane du composant connecté, si la largeur du composant connecté est 5 fois supérieure à la largeur médiane, ce composant connecté est le carré que nous recherchons. Les codes suivants sont utilisés pour illustrer cette idée xxx

les rectangles de sortie peuvent être affichés:

 Entrez la description de l'image ici Entrez la description de l'image ici


3 commentaires

Est-ce que cela va travailler pour des images numérisées? Les rectangles peuvent ne pas être parfaits, peut-être que les lignes pouvaient être effacées un peu ..


@Lulian Rosca cela fonctionnerait. Si les lignes ne sont pas bien détectées. Une possibilité est d'effectuer une dilatation pour l'image binaire afin que la ligne puisse être complètement détectée.


Pouvez-vous s'il vous plaît fournir un exemple de code comment faire cela?