IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Traitement d'images Discussion :

Seuillage pour binarisation d'image


Sujet :

Traitement d'images

  1. #1
    Membre régulier Avatar de zolotaya
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 93
    Points : 78
    Points
    78
    Par défaut Seuillage pour binarisation d'image
    Bonjour,
    Je cherche un algorithme simple me permettant de trouvé le seuil optimal pour une binarisation d'image.
    J'étais partis sur cet algo la : http://www.tsi.enst.fr/tsi/enseignem...a/isodata.html
    mais je n'ai pas trop les résultats espérés. (une erreur de codage n'est pas impossible mais j'ai déjà vérifié plusieurs foies et je n'en ai pas vu...)
    Serait'il possible d'avoir votre avis sur ce dernier et eventuellement m'orienté vers un algo meilleur.

  2. #2
    Membre régulier Avatar de riadh_ado
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations forums :
    Inscription : Avril 2006
    Messages : 90
    Points : 92
    Points
    92
    Par défaut Slt
    Citation Envoyé par zolotaya
    Je cherche un algorithme simple me permettant de trouvé le seuil optimal pour une binarisation d'image.

    Ce que tu dois comprendre est qu'il n'y a pas un seuil optimal ! Car tout dépend de l'image a binarisé. Mais je peut te renseigné sur les différentes méthode de seuillage
    1.Seuillage globale
    2.Seuillage locale
    3.Seuillage dynamique
    4.Seuillage par minimisation de variance
    5.Seuillage entropique
    6.Seuillage par classification bayesienne
    7.Seuillage par méthodes locales adaptatives
    8.Seuillage par ligne de partage des eaux
    9.............
    Donc plusieurs méthodes existent mais aucune ne peut pas donné un seuillage optimale (ce qui vous souhaitez !)
    [FONT=Times New Roman] A+[/FONT]

  3. #3
    Membre régulier Avatar de zolotaya
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 93
    Points : 78
    Points
    78
    Par défaut
    La ce serait pour un seuillage global.
    Jusque la, je prennais l'image et je la passée en niveaux de gris afin d'obtenir l'histogramme de cette derniere et faire mon seuillage à partir de celui ci.
    J'ai trouvé plusieurs algos mais j'en cherche un rapide, simple à mettre en oeuvre et efficace si possible.

  4. #4
    Membre régulier Avatar de riadh_ado
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : Tunisie

    Informations forums :
    Inscription : Avril 2006
    Messages : 90
    Points : 92
    Points
    92
    Par défaut
    Dificile a te repondre, mais si l'histogramme est bimodale tu peut appliqué l'algorithme qui tu as fait dans (http://www.tsi.enst.fr/tsi/enseignem...a/isodata.html)aprés un lissage par un filtre gaussienne.

  5. #5
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par riadh_ado
    Dificile a te repondre, mais si l'histogramme est bimodale tu peut appliqué l'algorithme qui tu as fait dans (http://www.tsi.enst.fr/tsi/enseignem...a/isodata.html)aprés un lissage par un filtre gaussienne.
    +1
    C'est exact.
    bi - modal est toujours plus facile.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 142
    Points : 93
    Points
    93
    Par défaut
    Bonjour,
    j'ai retrouvé ça, ça doit correspondre à ce que tu cherches je crois. Par contre, je n'ai pas eu le temps de re tester le code mais ça fonctionnait à l'époque.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
     
     
    void calculimage(Image &ima1,double &moy,int &eff)
    {
                 int h[256];
    	int i,somme;
    	histo(ima1,h);
    	eff=0;
    	somme=0;
    	for (i=0;i<256;i++)
    	{
    		eff=eff+h[i];
    		somme=somme+(h[i]*i);
    	}
    	moy=somme/eff;
    }
     
    void calculclass(Image &ima1,int seuilS,double &moyclasse0,double &effclasse0,double &proba0,double &moyclasse1,double &effclasse1,double &proba1)
    {
    	int h[256];
    	int i,somme0,somme1,imax;
    	double eff;
    	histo(ima1,h);
    	somme0=0;
    	somme1=0;
    	eff=0.0;
    	effclasse0=0;
    	effclasse1=0;
    	for (i=0;i<256;i++)
    	{
    		eff=eff+h[i];
    	}
    	imax=seuilS+1;
    	for (i=0;i<imax;i++)
    	{
    		effclasse0=effclasse0+h[i];
    		somme0=somme0+(h[i]*i);
    	}
    	if ((effclasse0==0)&&(somme0==0))
    	{
    		moyclasse0=0;
    		proba0=0;
    	}
    	else
    	{
    		moyclasse0=somme0/effclasse0;
    		proba0=effclasse0/eff;
    	}
     
     
    	for (i=imax;i<256;i++)
    	{
    		effclasse1=effclasse1+h[i];
    		somme1=somme1+(h[i]*i);
    	}
    	if ((effclasse1==0)&&(somme1==0))
    	{
    		moyclasse1=0;
    		proba1=0;
    	}
    	else
    	{
    		moyclasse1=somme1/effclasse1;
    		proba1=effclasse1/eff;
    	}
    }
     
    void seuilvar(Image &ima1,Image &ima2,int &s)
    {
    	int seuilS,eff,i,j,imax,jmax;
    	double var,varaux,moy,moyclasse0,moyclasse1,proba0,proba1,effclasse0,effclasse1;
    	varaux=0;
     
    	for (seuilS=0;seuilS<15;seuilS++)
    	{
    		calculimage(ima1,moy,eff);
    		calculclass(ima1,seuilS,moyclasse0,effclasse0,proba0,moyclasse1,effclasse1,proba1);
    		var=(proba0*(moyclasse0-moy)*(moyclasse0-moy))+(proba1*(moyclasse1-moy)*(moyclasse1-moy));
    		if (var>=varaux)
    		{
    			varaux=var;
    			s=seuilS;
    		}
    	}
    	imax=3*(int)ima1.largeur;
    	jmax=(int)ima1.hauteur;
    	for (i=0;i<imax;i+=3)
    	{
    		for (j=0;j<jmax;j++)
    		{
    			if ((ima1.ptrLigne[j][i]<=s)&&(ima1.ptrLigne[j][i+1]<=s)&&(ima1.ptrLigne[j][i+2]<=s))
    			{
    				memset(&ima2.ptrLigne[j][i],0,3);
    			}
    			else
    			{
    				memset(&ima2.ptrLigne[j][i],255,3);
    			}
    		}	
    	}
     
    }
     
    void histo(Image &ima1,int h[256])
    {
    	int i,imax;
    	for (i=0;i<256;i++)	
    	{
    		h[i]=0;
    	}
    	imax=(int)ima1.largeur*(int)ima1.hauteur;
    	for (i=0;i<imax;i++)
    	{
    		h[ima1.pixel[i]]=h[ima1.pixel[i]]+1;
    	}
    }
    Pour moi, Image est une structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    typedef struct {
    	unsigned long    hauteur;
    	unsigned long    largeur;
    	unsigned char    type; // BINARY, GRAY ou RGB 
    	unsigned char*   pixel;
    	unsigned char**  ptrLigne;
    //	int nbpix;
    } Image;
    Ce code est un peu vieux, c'était mes débuts en traitement d'image. Il y a surement moyen de l'optimiser.....

  7. #7
    Membre régulier Avatar de zolotaya
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 93
    Points : 78
    Points
    78
    Par défaut
    Citation Envoyé par poukill
    +1
    C'est exact.
    bi - modal est toujours plus facile.
    La le problème pour mon histo Bi-modale est que j'ai beaucoup de bruit ce qui signifie que mon intervalle des valeurs non nul est super grand (souvent entre 0 et 255 ) alors que mes 2 classes sont super rapprochées (j'ai une images ou mes 2 piques sont à 8 et 44 )
    Lorsque j'applique l'algos trouvé, il vas me diviser mon histo en 2 parties avec un seuil initiale à 128 et faire les moyennes à partir de ce seuil pour finir pas m'en trouvé un beaucoup trop haut à 141...
    à votre avis une erreur de codage est possible ou le problème est due aux valeurs initiales? (ou les 2?)

  8. #8
    Membre éclairé
    Avatar de parp1
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    829
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Mai 2005
    Messages : 829
    Points : 872
    Points
    872
    Par défaut
    Et bien peut etre qu'un Prétraitement comme une érosion... Peux tu faire un pré traitement avant ton seuillage par hsitogramme.

  9. #9
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 084
    Points
    16 084
    Par défaut
    Sinon tu peut faire un k-mean a 2 regions. Apres tout, l'iso-data et le k-mean se ressemblent beaucoup...

  10. #10
    Membre régulier Avatar de zolotaya
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 93
    Points : 78
    Points
    78
    Par défaut
    J'avais déja essayer de faire une fermeture comme pré traitement mais cela ne m'a rien donner de bon (du moin pour ce que je voulais).
    La j'ai essayé une convolution afin de lisser un peu mon image mais je pense qu'il vas falloir que je revoie mon filtre car les résultats sont plutot bizar...
    (je vais peu etre devoir reecrire une formule de convolution car je pense que celle que j'utilise y est pour beaucoup ...)

  11. #11
    Membre éprouvé
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Points : 1 158
    Points
    1 158
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par zolotaya
    La le problème pour mon histo Bi-modale est que j'ai beaucoup de bruit ce qui signifie que mon intervalle des valeurs non nul est super grand (souvent entre 0 et 255 ) alors que mes 2 classes sont super rapprochées (j'ai une images ou mes 2 piques sont à 8 et 44 )
    Lorsque j'applique l'algos trouvé, il vas me diviser mon histo en 2 parties avec un seuil initiale à 128 et faire les moyennes à partir de ce seuil pour finir pas m'en trouvé un beaucoup trop haut à 141...
    à votre avis une erreur de codage est possible ou le problème est due aux valeurs initiales? (ou les 2?)
    Est-ce que tu as Photoshop ? sinon ImageJ qui est opensource. Pour du traitement d'image, j'aime bien jouer avec l'image d'abord dans un environnement confortable qui me permet d'essayer beaucoup de solutionss. quand j'ai une stratégie qui marche, je peux la coder en dur. (et même avant ça, je fais une maquette (dans mon cas ave PhotoShop) sous forme de script que je teste intensivement sur d'autres images.

    Tout ça pour dire que seuillage, floutage, débruitage, et extraction d'histogramme sont des méthodes faciles à tester avec tohop ou imagej.

    OL

  12. #12
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    ou matlab... c'est très bien aussi !

  13. #13
    Membre régulier Avatar de zolotaya
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 93
    Points : 78
    Points
    78
    Par défaut
    Je code directement en JAVA vu que c'est pour une appli JAVA.
    Sinon mon problème de bruit n'est pas résolu, car meme aprés filtrage mes points blanc sur fond noir virent au gris, alors que la région que je veux "rendre blanche" et qui est déja pas mal foncée d'origine, l'est encore plus...

    Quelqu'un connait'il un algo de détéction des modes dans un histogramme?

  14. #14
    Membre éclairé
    Avatar de parp1
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    829
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Mai 2005
    Messages : 829
    Points : 872
    Points
    872
    Par défaut
    Peut tu nous joindre une image.

    Peut etre qu'une simple convolution par le noyaux

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    |1|1|1|
    |1|1|1|
    |1|1|1|
    Peut deja bien aider?

  15. #15
    Membre régulier Avatar de zolotaya
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 93
    Points : 78
    Points
    78
    Par défaut
    voila l'image :


    j'ai deja essayer un masque ( 1 1 1 / 1 2 1 / 1 1 1 ) et un masque ( 1 1 1 / 1 1 1 / 1 1 1 ).
    Il y a deux "problèmes".
    Le premier est qu'il ne faut pas (ou le moin possible) que je touche aux fronts des barres.
    Le deuxieme est qu'une détéction des région n'est pas possible. Sur certaines images le haut des codes à barres touches des grosses régions noir. Il me detecte donc que quelques barres.
    J'ai commancer à réfléchir sur une éventuelle détéction des contours, mais ca s'annonce chian aprés pour récupérer la tailles des barres aprés...

  16. #16
    Membre éclairé
    Avatar de parp1
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    829
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Mai 2005
    Messages : 829
    Points : 872
    Points
    872
    Par défaut
    Je te met ce que j'arrive a sortir.

    Tout d'abords j'ai appliquer un Rolling Ball de 50 de large pour soustraire le fond. (A optimiser)
    --> premiere Image

    Ensuite un seuil double (j'ai oublier les valeurs ... mais elle n'étaient optimisées)

    --> image.

    Ensuite j'imagine qu'il va falloir faire de la reconnaissance de caracteres... Bon courage.

    [Edit]J'ai essayer un truc tout Bete.... l'étalement d'histogramme+ une amélioration de contraste de +0.5%(Process --> EnhanceContrast sous ImageJ (Option par defaut juste avec Equalize Histogramme de validé), et juste avec un seuillage j'obtient la troisieme image.
    Un coup de morpho et le probleme est réglé. [/edit]
    Images attachées Images attachées    

  17. #17
    Membre régulier Avatar de zolotaya
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 93
    Points : 78
    Points
    78
    Par défaut
    tu peux essayer la meme chose avec cette image la ?

    http://img504.imageshack.us/img504/1...arcode3vc9.jpg
    (Mon pb est que lorsque ca marche avec l'une, ca marche pas avec l'autre...)

    Sinon c'est quoi un Rolling Ball? tu as fait comment ton étirement d'histogramme car sur l'image il y a des valeurs allant de 0 à 255... ?

  18. #18
    Membre éclairé
    Avatar de parp1
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    829
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Mai 2005
    Messages : 829
    Points : 872
    Points
    872
    Par défaut
    Un rolling bAll est un algorythme de soustraction de fond.
    Citation Envoyé par zolotaya
    tu as fait comment ton étirement d'histogramme car sur l'image il y a des valeurs allant de 0 à 255... ?
    En théorie Oui. Mais par exemple sur ton image les valeur les plus basse ne sont pas a zero... le truc consiste a remanier l'histogramme en disant...

    La plus petite valeur Acquise = 0
    La plus Grande valeur acquise = 255. C'est un bete calcul de pente...
    Tu devrais trouver plein d'aglo deja tout fait.

    tu peux trouver des sources en C, Cherche un sujet dans ce forum intitulé : Fermeture des contours.

    Le resultat ici est moin bon mais tout a fait exploitable.

    Il suffis que tu fasse une ouverture avec une element structurant de ce type et de grande taille si possible. J'ai d'abord passe l'image en Grey Level 8 Bits.

    Mais je ne sais pas ce que tu obtenais avant ... donc je ne sais pas si c'est mieu ou non. Est ce que seul la largeur des barre t'interesse... je pense qu oui car c'est la dedans qu'est stocke l'info il me semble....
    Images attachées Images attachées  

  19. #19
    Membre régulier Avatar de zolotaya
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    93
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 93
    Points : 78
    Points
    78
    Par défaut
    Pour la deuxieme image j'obtenais quelque chose de similaire mais en noir et blanc...

    Et oui seul la largeur des barres m'intersse mais ca normalement c'est bon^^

    Sinon le truc c'est que normalement je recois l'image scannée (l'une ou l'autre voir des pires ) et je dois ressortir la valeurs du code à barres. Tout le reste doit se faire tout seul --> d'ou mon dépard sur le seuillage adaptatif...
    Autrement que ce soit une image ou l'autre, le traitement à effectuer doit toujours etre le même ou tout du moin automatisable --> mon pb actuellement!
    Sinon j'ai regarder pour le rolling ball, les paramétres doivent pouvoir etre défini en changent d'espace colorimétrique et en recherchant le taux de luminositée et tt mais bon ... Grosse prise de tête en perspective...
    Sauf si quelqu'un à une idée ...

  20. #20
    Membre éclairé
    Avatar de parp1
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    829
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Mai 2005
    Messages : 829
    Points : 872
    Points
    872
    Par défaut
    Mais a tu une idée de la source dont provienne tes Images... Est ce des codes barre tjr identique?

    Ou bien des code barres pris au hasard d'un peu partout?

    Je sais que l'idéal serait que ton programme fonctionne avec n'importe quelle image.


    Un truc encore plus simple. Apres une Amelioration de contraste essaie de faire un soustraction du genre:
    Faire le Dilaté d'une image moins celle ci.

    Dilate(Image)-Image

    Tu devrais obtenir le contour de ton image. Reste plus cas faire un remplissage de trous.

    Je suis septique sur cette piste. Mais essaie.


    Bon je suis en Week End j'espere que lundi tu auras du nouveau.


    Juste une derniere chose. L'étalage de l'histogramme et l'amélioration est robuste puisqu'il depend que de l'image. Donc ca vu les resultats je pense qu'il faut l'exploiter. Je ne sais pas si tu connais le seuil Entropique.?

    Moi c'est un seuil que j'utilise parfois pour du seuillage auto, mais je crains que ca ne soit pas exploitable pour de la recherche de caractere. mais faut Tester c'est facile a implémenter. Sinon tu a un plugin pour ImageJ. Bon courage.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 0
    Dernier message: 12/01/2014, 22h34
  2. Binarisation d'image pour détection de formes
    Par babarpapa dans le forum Traitement d'images
    Réponses: 12
    Dernier message: 09/05/2006, 15h32
  3. Réponses: 13
    Dernier message: 23/12/2004, 18h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo