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 :

Sobel (dérivée suivant Y)


Sujet :

Traitement d'images

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 12
    Points : 8
    Points
    8
    Par défaut Sobel (dérivée suivant Y)
    Bonjour,

    Après avoir lu les pseudo-algorithmes sur le filtre de Sobel, j'ai décidé de l'implémenter en C++ / OpenCV. Mais je me retrouve face à des problèmes "de compréhension".

    J'obtiens à priori un bon résultat en X mais pas en Y (voir fichiers ci-joints).

    Dois-je remplacer le noyau par la norme de la matrice Gx (et ensuite Gy) ?
    J'ai compris que pour le résultat je dois calculer la norme de Gx + Gy.

    Si quelqu'un peut m'indiquer mes erreurs éventuels ...
    Merci.

    PS : J'ai changé le code pour qu'il puisse tester séparément Gx et Gy
    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
        void filtreSobel(IplImage *src, IplImage *dst)
        {
            CvScalar scalaire;
     
            float SobelX[]={-1, 0, 1, -2, 0, 2, -1, 0, 1};
            float SobelY[]={1, 2, 1, 0, 0, 0, -1, -2, -1};
            CvMat M_SobelX = cvMat(3, 3, CV_32FC1, SobelX);
            CvMat M_SobelY = cvMat(3, 3, CV_32FC1, SobelY);
            CvMat *M_Tmp = cvCreateMat(3,3,CV_32FC1);
            CvMat *M_Tmp2 = cvCreateMat(3,3,CV_32FC1);
            float *data_M_Tmp = M_Tmp->data.fl; 
     
             for (int x=1; x<src->width-1; x++)
             {
                for (int y=1; y<src->height-1; y++)
                {
                    CvRect mon_rectangle = cvRect(x-1, y-1, 3 , 3);
                    //Je définis la région d'intérêt de mon image.
                    cvSetImageROI(src, mon_rectangle);
                    cvSetImageROI(dst, mon_rectangle);
                    for (int tmp_x=0; tmp_x<3; tmp_x++)
                    {
                        for (int tmp_y=0; tmp_y<3; tmp_y++)
                            data_M_Tmp[tmp_x*3+tmp_y] = (float)(cvGet2D(src, tmp_x, tmp_y)).val[0];
                    }
                    cvMatMul(&M_SobelY, M_Tmp, M_Tmp2);
                    if (cvmGet(M_Tmp2,1,1)<0)
                        scalaire.val[0] = 0;
                    else if (cvmGet(M_Tmp2,1,1)>255)
                        scalaire.val[0] = 255;
                    else
                        scalaire.val[0] = (int)cvmGet(M_Tmp2,1,1);
                    cvSet2D (dst, 1, 1, scalaire);
                    //Maintenant je relâche la région d'intérêt 
                    cvResetImageROI(src);
                    cvResetImageROI(dst);
                }
            }
        }
    Images attachées Images attachées   

  2. #2
    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 081
    Points
    16 081
    Par défaut
    Pour faire un filtrage linéaire avec un noyau (sobel ou autre), il ne faut pas utiliser la multiplication de matrice traditionnelle "cvMatMul" mais un produit de convolution.

    Tu peux calculer ce produit de convolution en faisant la multiplication terme à terme des 2 matrices par "cvMul" et en calculant la somme des termes dans la matrice résultante.

    Ou alors utiliser directement la fonction cvFilter2D.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    Cool, merci pour la réponse rapide et efficace !
    Ça marche maintenant.

    Une petite question sur CvMul, pour avoir la norme du gradient, il me suffit juste d'écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CvMul(Gx,Gx,n_Gx);
    CvMul(Gy,Gy,n_Gy);
    norme_du_gradient = CvSqrt( CvAdd( n_Gx + n_Gy ) );
    Est-ce correct ?

  4. #4
    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 081
    Points
    16 081
    Par défaut
    Citation Envoyé par DyoXynE Voir le message
    Cool, merci pour la réponse rapide et efficace !
    Ça marche maintenant.

    Une petite question sur CvMul, pour avoir la norme du gradient, il me suffit juste d'écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    CvMul(Gx,Gx,n_Gx);
    CvMul(Gy,Gy,n_Gy);
    norme_du_gradient = CvSqrt( CvAdd( n_Gx + n_Gy ) );
    Est-ce correct ?
    Tu n'as pas besoin de passer par des multiplications de matrices.

    Le vecteur gradient pour un pixel (x,y) à pour coordonnées (gx,gy) :
    gx = convolution par sobelX au voisinage de (x,y) = un scalaire
    gy = convolution par sobelY au voisinage de (x,y) = un autre scalaire

    La norme du vecteur est "racine(gx² + gy²)"
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 12
    Points : 8
    Points
    8
    Par défaut
    Bon bah finalement j'ai compris en regardant plusieurs cours sur internet ...

    Un dernier problème est : à quoi correspond l'orientation : arctan (fx/fy) ?
    Je ne comprends pas.

  6. #6
    Membre actif
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    219
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 219
    Points : 226
    Points
    226
    Par défaut
    L'orientation te donne la direction (locale) des contours.

Discussions similaires

  1. Dérivée d'une image : gradients et filtre de Sobel
    Par betsprite dans le forum Traitement d'images
    Réponses: 12
    Dernier message: 22/12/2010, 19h54
  2. projet suivant le principe de MSN
    Par Walm dans le forum Développement
    Réponses: 2
    Dernier message: 30/09/2003, 12h36
  3. Lettre Drive lecteur de CDRom
    Par titicurio dans le forum C++Builder
    Réponses: 4
    Dernier message: 18/09/2003, 13h44
  4. langage] Découper une chaine suivant un délimiteur
    Par totox17 dans le forum Langage
    Réponses: 2
    Dernier message: 25/11/2002, 16h25
  5. Réponses: 3
    Dernier message: 22/07/2002, 14h19

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