Quels sont les meilleurs algorithmes de seuillage d'image de document dans cet exemple?

31

J'essaie d'implémenter divers algorithmes de binarisation sur l'image présentée: entrez la description de l'image ici

Voici le code:

clc;
clear;
x=imread('n2.jpg');     %load original image

% Maintenant, nous redimensionnons les images afin que le travail de calcul devienne plus facile pour nous plus tard.

size(x);
x=imresize(x,[500 800]);
figure;
imshow(x);
title('original image');

z=rgb2hsv(x);       %extract the value part of hsv plane
v=z(:,:,3);
v=imadjust(v);

% maintenant, nous trouvons la moyenne et l'écart type requis pour les algorithmes niblack et% sauvola

m = mean(v(:))
s=std(v(:))
k=-.4;
value=m+ k*s;
temp=v;

% implémentation d'un algorithme de seuillage niblack:

for p=1:1:500
    for q=1:1:800
        pixel=temp(p,q);
        if(pixel>value)
            temp(p,q)=1;
        else
            temp(p,q)=0;
        end
    end
end
figure;
imshow(temp);
title('result by niblack');
k=kittlerMet(g);
figure;
imshow(k);
title('result by kittlerMet');

% implémentation de l'algorithme de seuillage sauvola:

val2=m*(1+.1*((s/128)-1));
t2=v;
for p=1:1:500
for q=1:1:800
    pixel=t2(p,q);
    if(pixel>value)
        t2(p,q)=1;
    else
        t2(p,q)=0;
    end
end

fin

figure;
imshow(t2);
title('result by sauvola');

Les résultats que j'ai obtenus sont les suivants: entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici

Comme vous pouvez le voir, les images résultantes sont dégradées aux endroits les plus sombres. Quelqu'un pourrait-il suggérer comment optimiser mon résultat ??

marque
la source
1
Pouvez-vous utiliser les informations de couleur pour jeter l'arrière-plan au lieu de la luminosité uniquement?
endolith
Respecté Monsieur / Madame. Je fais un projet sur le traitement d'image.Je suis un concept de binarisation intéressant..Veuillez vérifier et corriger le codage ... Je prends le codage et exécute le programme.Mais une erreur se produit ce codage ... Fonction indéfinie ou variable "g". et un autre est Erreur dans msp (ligne 31) k = kittlerMet (g); .. Comment le résoudre ... Veuillez corriger le codage ...
muthu

Réponses:

49

Votre image n'a pas une luminosité uniforme, vous ne devez donc pas travailler avec un seuil uniforme. Vous avez besoin d'un seuil adaptatif. Cela peut être implémenté en prétraitant l'image pour rendre la luminosité plus uniforme à travers l'image (code écrit en Mathematica, vous devrez implémenter la version Matlab pour vous-même):

Un moyen simple pour uniformiser la luminosité consiste à supprimer le texte réel de l'image à l'aide d'un filtre de fermeture:

white = Closing[src, DiskMatrix[5]]

entrez la description de l'image ici

La taille du filtre doit être choisie supérieure à la largeur du trait de police et inférieure à la taille des taches que vous essayez de supprimer.

EDIT: On m'a demandé dans les commentaires d'expliquer ce que fait une opération de clôture. C'est une dilatation morphologique suivie d'une érosion morphologique . La dilatation déplace essentiellement l'élément structurant à chaque position de l'image et sélectionne le pixel le plus lumineux sous le masque, ainsi:

  • enlever les structures sombres plus petites que l'élément structurant
  • rétrécissement des structures sombres plus grandes par la taille de l'élément structurant
  • agrandissement de structures lumineuses

L'opération d'érosion fait le contraire (elle sélectionne le pixel le plus sombre sous l'intérieur de l'élément structurant), donc si vous l'appliquez sur l'image dilatée:

  • les structures sombres qui ont été enlevées parce qu'elles sont plus petites que l'élément structurant sont toujours parties
  • les structures plus sombres qui ont été rétrécies sont à nouveau agrandies à leur taille d'origine (bien que leur forme soit plus lisse)
  • les structures lumineuses sont réduites à leur taille d'origine

Ainsi, l'opération de fermeture supprime les petits objets sombres avec seulement des modifications mineures aux objets sombres plus gros et aux objets lumineux.

Voici un exemple avec différentes tailles d'éléments structurants:

entrez la description de l'image ici

À mesure que la taille de l'élément structurant augmente, de plus en plus de caractères sont supprimés. Au rayon = 5, tous les caractères sont supprimés. Si le rayon est encore augmenté, les petites taches sont également supprimées:

entrez la description de l'image ici

Il vous suffit maintenant de diviser l'image originale par cette "image blanche" pour obtenir une image de luminosité (presque) uniforme:

whiteAdjusted = Image[ImageData[src]/ImageData[white]*0.85]

entrez la description de l'image ici

Cette image peut maintenant être binarisée avec un seuil constant:

Binarize[whiteAdjusted , 0.6]

entrez la description de l'image ici

Niki Estner
la source
5
Hou la la! C'est vraiment cool! Énorme +1!
Phonon
@nikie +1 Très bien - que voulez-vous dire exactement en fermant le filtre doit être "choisi plus grand que le trait de police"? Largeur ou longueur d'une lettre? De plus, que fait «vraiment» un filtre de fermeture? Merci!
Spacey
1
@Mohammad: J'ai ajouté une petite explication à ma réponse. Et oui, ce sont des opérations non linéaires. Le titre commun est le traitement d'images morphologiques.
Niki Estner
1
@nikie Peu importe, le blanc est le maximum, pas le noir. :-)
Spacey
1
@gdelfino: J'essaie généralement de l'éviter en utilisant un masque assez grand et en utilisant Clip[ImageData[white],{eps,Infinity}]où eps est un petit nombre, pour être sûr.
Niki Estner
6

La réponse de Nikie semble la meilleure et semble également fonctionner et produire des résultats. C'est donc clairement un gagnant.

Cependant, juste pour la documentation, j'ajoute une référence de plus, cela pourrait être très rapide.

Cette technique est appelée seuillage adaptatif qui ne nécessite pas d' apprendre explicitement l'arrière-plan.

Essentiellement, au lieu de trouver le seuil global le plus approprié - nous pouvons partitionner l'image dans une fenêtre locale (disons environ 7x7 ou appropriée) et trouver des seuils qui changent au fur et à mesure que la fenêtre traverse.

La référence ci-dessous détaille la méthode exacte. http://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm

Cette méthode serait relativement plus rapide sur le plan informatique.

Dipan Mehta
la source
Ces deux choses ne sont-elles pas essentiellement les mêmes? À savoir estimer la moyenne locale du signal avant le seuillage?
Maurits
1
@Maurits Il semble que les principales différences soient le classement et les statistiques utilisées. Par exemple, dans les opérateurs d'ouverture / fermeture (qui sont constitués de dilatation et d'érosion mais dans un ordre différent), une fenêtre est scannée raster et max est prise. (Entre autres). Cependant, dans le seuil adaptatif, la moyenne / médiane peut être prise au lieu du max.
Spacey
OP l'a également demandé sur SO , à laquelle j'ai répondu. Mais en principe, je ne pense pas qu'il y ait de différence entre les réponses, on est toujours en train d'estimer les statistiques locales. Si vous effectuez un seuillage adaptatif, vous apprenez également l'arrière-plan du processus.
Maurits
6

Une autre façon d'utiliser un filtre passe-bande (dans MATLAB). Jouer avec la différence des paramètres gaussiens peut donner de meilleurs résultats. Le processus consiste essentiellement à filtrer la bande passante de l'image pour supprimer les taches de fond à basse fréquence, normaliser à [0,1] requis pour la commande «graythresh», image de seuil.

Charger l'image et la convertir en niveaux de gris double:

I = imread('hw.jpg');
I = rgb2gray(I);
I = double(I);

entrez la description de l'image ici

Filtrer en utilisant la différence du noyau gaussien et normaliser:

J = imgaussian(I,1.5) - imgaussian(I,0.5);
J = J - min(J(:));
J = J / max(J(:));

entrez la description de l'image ici

Calculez le seuil et faites 010101:

T = J > graythresh(J);

entrez la description de l'image ici

geometrikal
la source
4

Il s'agit d'un bon code Matlab pour le seuillage adaptatif: http://www.mathworks.com/matlabcentral/fileexchange/8647-local-adaptive-thresholding

MyCarta
la source
Argh! Nécessite cependant la boîte à outils de traitement d'image. : - /
Spacey
Effectivement. Désolé si vous ne l'avez pas. Mais DIPImage est une Tolbox Image gratuite pour Matlab. diplib.org/documentation Il a quelques méthodes de seuillage (vérifier la section de segmentation) et vous pouvez également faire toutes les opérations morphologiques comme la fermeture. Le développeur a également un blog cb.uu.se/~cris/blog/index.php/archives/tag/matlab
MyCarta
0

Je vais essayer ce codage, mais je n'ai pas de bonne réponse ...

clc;
clear;
x=imread('base2.jpg');
size(x);
x=imresize(x,[500 800]);
figure;
imshow(x);
title('original image');
z=rgb2hsv(x);       %extract the value part of hsv plane
v=z(:,:,3);
v=imadjust(v);
m = mean(v(:))
s=std(v(:))
k=-2;
value=m+ k*s;
temp=v;
for p=1:1:500
    for q=1:1:800
        pixel=temp(p,q);
        if(pixel>value)
            temp(p,q)=1;
        else
            temp(p,q)=0;
        end
    end
end
figure;
imshow(temp);
title('result by niblack');
% k=kittlerMet(g);
% figure;
% imshow(k);
% title('result by kittlerMet');

val2=m*(1+.1*((s/128)-1));
t2=v;
for p=1:1:500
for q=1:1:800
    pixel=t2(p,q);
    if(pixel>value)
        t2(p,q)=1;
    else
        t2(p,q)=0;
    end
end

end
figure;
imshow(t2);
title('result by sauvola');

entrez la description de l'image ici

entrez la description de l'image ici

muthu
la source
2
Si cela vise à répondre à la question, veuillez expliquer ce que vous faites et pourquoi.
Matt L.