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 :

Implémenter sobel et calculer son gradient


Sujet :

Traitement d'images

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    95
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 95
    Par défaut Implémenter sobel et calculer son gradient
    Bonjour à tous, j'ai besoin d'un peu d'aide pour comprendre et finir mon bout de code.

    Pas très original, je souhaite implémenter l'algorithme de sobel (en vue d'une implé de canny edge par la suite...).

    Je ne vois pas comment calculer la norme du gradient G = sqrt(Gx²+Gy²) avec les éléments que j'ai déjà :

    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
    void sobel(IplImage *src, IplImage *dst, bool dir){
     
        // Masques de convolution
    	CvMat* sobel = cvCreateMat( 3, 3, CV_32FC1);
        cvSet( sobel, cvScalar( 0 ) );
    	if( dir == true){
    		cvmSet( sobel, 0, 0,-1);
    		cvmSet( sobel, 0, 2,1);
    		cvmSet( sobel, 1, 0,-2);
    		cvmSet( sobel, 1, 2,2);
    		cvmSet( sobel, 2, 0,-1);
    		cvmSet( sobel, 2, 2,1);
    	}
    	else{
    		cvmSet( sobel, 0, 0,1);
    		cvmSet( sobel, 0, 1,2);
    		cvmSet( sobel, 0, 2,1);
    		cvmSet( sobel, 2, 0,-1);
    		cvmSet( sobel, 2, 1,-2);
    		cvmSet( sobel, 2, 2,-1);
    	}
        cvFilter2D( src, dst, sobel );
     
    int main(){
         IplImage * src = cvLoadImage("xxxx.png",1);
         IplImage * src = cvLoadImage("xxxx.png",1);
         IplImage *gray = cvCreateImage(cvSize(img->width,img->height),IPL_DEPTH_8U,1);
         IplImage *sobx = cvCloneImage(gray);
         IplImage *soby = cvCloneImage(gray);
         IplImage *sobine = cvCloneImage(gray);
     
        sobel(gray,sobx,1);
    		sobel(gray,soby,0);
    		CvScalar p1,p2,p3;
     
    		for(int x=0;x<img->width;x++){
    			for(int y=0;y<img->height;y++){
    				p1 = cvGet2D(sobx,y,x);
    				p2 = cvGet2D(soby,y,x);
    				p3.val[0] = sqrt(p1.val[0]*p1.val[0] +                     p2.val[0]*p2.val[0]);
    				cvSet2D(sobine,y,x,p3);
    			}
    		}
     
    // Que faire de sobx et soby sachant que je souhaite leur norme dans sobine ?
     
    }
    Merci par avance pour l'aide !

    Edit : Je pense que je me suis trompé sur ma compréhension de la norme du gradient donc je pouvais pas progresser. Je pense que j'ai résolu mon problème et j'ai mis à jour mon code. Est-ce que vous pouvez me dire si j'ai bon ou pas ?

  2. #2
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Par défaut
    Bonjour,

    est ce que le code du gradient de Sobel fonctionne correctement ?
    As tu affiché le résultats sur des images ?
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  3. #3
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    95
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 95
    Par défaut
    Bonjour Toto,

    Le code du sobel ne marche pas correctement, et je ne m'en suis aperçu qu'aujourd'hui... (bon en même temps j'ai pas passé les 7 derniers jours là-dessus ^^).

    Voilà l'image que cela m'affiche :


    Uploaded with ImageShack.us


    On peut voir que tous les contours ne sont pas détectés (marqué en blanc / gris) mais on peut aussi voir que les contours qui devraient être détectés sont marqués en noir (le chapeau, l'épaule et le bras).

    Je pense que c'est en noir car la valeur dépasse 255 et je pense que c'est la fonction cvFilter2D qui fait ca. Je ne peux donc pas rajouter de condition pour qu'il me fixe correctement ma valeur...

    Mon nouveau soucis c'est que je n'arrive pas à implémenter une convolution 2D en C++.... et si quelqu'un a un algo simple à implémenter je suis preneur ! Il faut vraiment que j'avance sur mon projet et là je prends du retard ...

  4. #4
    Membre Expert
    Avatar de kmaniche
    Inscrit en
    Janvier 2006
    Messages
    1 717
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 717
    Par défaut
    Pour la détection de contours, le calcul du gradient n'est qu'une étape. Il te faut par la suite l'extraction des maximas locaux et le seuillage par hystérésis.

  5. #5
    Membre Expert
    Avatar de kmaniche
    Inscrit en
    Janvier 2006
    Messages
    1 717
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 717
    Par défaut
    Pour la convolution :
    Soit un masque de convolution Msk de 3x3 et l'image Im de taille H et W

    La convolution de l'image Im par le masque Msk consiste à faire balayer le masque sur l'image, et pour chaque pixel central, remplacer sa valeur par le somme du produit des pixels voisins avec le masque, ensuite passer au balayage suivant.

    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
    Msk = ( -1 0 1
           -2 0 2
           -1 0 1) / 9
    
    pour i de 1 à H-1
     pour j de 1 à W-1
         pour k de i-1 à i+1
             sm = 0 ;
            pour p de j-1 à j+1
                  sm = sm+ Im(k, p) *Msk(k-i+2, p-j+2) ;
            fin
         fin
          Ir(i, j) = sm ;
      fin
    fin

  6. #6
    Membre confirmé
    Inscrit en
    Juin 2008
    Messages
    95
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 95
    Par défaut
    Salut Kmaniche et merci de ton aide,

    J'ai implémenté ton pseudo-code, malheureusement l'image final est toute blanche (excepté les bords), tous les pixels ont une valeur supérieur à 255.

    Est-ce que tu pourrais me corriger stp ? Je m'en sors pas je me perds dans les indices, j'ai pas de vision de ce que je fais...

    Merci pour l'aide

    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
    void canny(IplImage *src, IplImage *dst){
    	CvScalar scalar;
     
    	int sizex = (src->height);
    	int sizey = (src->width);
    	int sumX = 0;
     
    	int **KX;
    	// Kernel init
    	KX = new int*[3];
    	for (int i = 0; i < 3; i++)
    	{
    		KX[i] = new int[3];
    		for(int j=0;j<3;j++){
    			KX[i][j] = 0;
    		}
    	}
     
    	KX[0][0] = -1;
    	KX[0][1] = -2;
    	KX[0][2] = -1;
     
    	KX[2][0] = 1;
    	KX[2][1] = 2;
    	KX[2][2] = 1;
     
     
    	for(int x=0;x<sizex;x++){
    		for(int y=0;y<sizey;y++){
     
    			for( int k=x-1;k<x+1;k++){
    				for(int p=y-1;p<y+1;p++){
     
    					if(k>0 && p>0){
    						scalar = cvGet2D(src,p,k); // the value of the pixel [k,p]
    						sumX = sumX + scalar.val[0] * KX[k-x+2][p-y+2];
    					}
    				}
    			}
    			if(sumX > 255) sumX = 255;
    			if(sumX < 0) sumX = 0;
    			scalar.val[0] = sumX;
    			cvSet2D(dst,y,x,scalar);
    		}
    	}
    }
    ps : Le but c'est de détecter des cercles par transformé de Hough, donc j'en suis à l'étape CannyEdge

Discussions similaires

  1. calcul de gradient entre deux images
    Par enita dans le forum Images
    Réponses: 5
    Dernier message: 28/05/2013, 13h14
  2. Comment optimiser le calcul du gradient d'une image dans matlab
    Par MPEG4 dans le forum Traitement d'images
    Réponses: 19
    Dernier message: 28/04/2009, 18h36
  3. calculer le gradient d'un polynome avec matlab
    Par wajdiisi2007 dans le forum MATLAB
    Réponses: 2
    Dernier message: 18/01/2009, 22h34
  4. Réponses: 2
    Dernier message: 06/07/2002, 12h36

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