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émentation du détecteur de Harris


Sujet :

Traitement d'images

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur vision
    Inscrit en
    Janvier 2013
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur vision
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2013
    Messages : 23
    Points : 29
    Points
    29
    Par défaut Implémentation du détecteur de Harris
    Bonjour à tous,

    Je suis en train d'implémenter en C++ le détecteur de Harris, et je me pose des questions sur les résultats de mon algorithme.

    Voici un pseudo-code l'expliquant :

    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
     
    Paramètres de ma fonction : img_src : tableau 2D image d'entrée, img_dst : tableau 2D image de sortie, Gauss : valeur de lissage gaussien, k : coefficient 0.04 (peut aller jusqu'à 0.06), threshold : ma valeur de seuil, corner_Harris : un vector remplie avec les coordonées en x et en y de mes points.
     
    J'applique la dérivée de Sobel [-1 -2 -1; 0 0 0; 1 2 1] et [-1 0 1; -2 0 2; 1 0 2] pour obtenir deux tableaux 2D des dérivées en x et en y.
     
    Si Gauss > 0, j'applique un lissage gaussien selon la valeur de Gauss.
     
    Je parcours img_src pour obtenir 3 variables : A, qui correspond aux Ix²; B, qui correspond aux Ixy; et C, qui correspond aux Iy².
     
    Je calcule la réponse : réponse = (A * C - B * B) - k * (A + B) * (A + B);
     
    Si ma réponse est supérieur à threshold, je garde la valeur (que je ramène entre [0; 255]). Sinon, mon pixel vaut 0.
     
    Il faut savoir que le calcul de A, B et C se faite dans une fenêtre 3*3 autour du pixel étudiée.
     
    Une fois ce calcul fait sur tous les pixels de l'image, je calcule les maxima locaux pour n'obtenir que les plus forts points. Le calcule est fait sur une fenêtre 3*3 autours du pixel étudié.
     
    Je refais un dernier tour pour obtenir la position [x, y] de chaque point pour remplir mon vecteur std::vector, ces points devant être des coins.
    Je souhaiterai savoir deux choses : que pensez-vous de mon algo' ? (Je peux mettre une version c++ si besoin).
    Est-il possible d'améliorer les résultats ? J'ai l'impression d'avoir des erreurs sur certaines images complexes... notamment l'image de Lena, que j'utilise souvent comme image test. Je n'obtiens rien ! Mais je ne sais si l'erreur est dû à mon calcul de A, B et C, où à ma recherche de maxim locaux.

    Merci d'avance pour l'aide/commentaire

    Axel

  2. #2
    Membre éprouvé

    Homme Profil pro
    Cyber Security & AI
    Inscrit en
    Février 2009
    Messages
    506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Cyber Security & AI

    Informations forums :
    Inscription : Février 2009
    Messages : 506
    Points : 1 189
    Points
    1 189
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    Je ne suis pas sûr de ta dérivé de Sobel, mais sinon le reste me semble juste.

    Bien cordialement.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur vision
    Inscrit en
    Janvier 2013
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur vision
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2013
    Messages : 23
    Points : 29
    Points
    29
    Par défaut
    Bonjour dev_ggy,

    Penses-tu à solution particulière pour calculer les dérivées ?

    J'ai une autre question : est-il possible d'améliorer la recherche des coins grâce à cette algorithme ?

    Cordialement,

    Axel
    Images attachées Images attachées  

  4. #4
    Membre éprouvé

    Homme Profil pro
    Cyber Security & AI
    Inscrit en
    Février 2009
    Messages
    506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Cyber Security & AI

    Informations forums :
    Inscription : Février 2009
    Messages : 506
    Points : 1 189
    Points
    1 189
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    Citation Envoyé par Foxaltex
    Penses-tu à solution particulière pour calculer les dérivées ?
    et

    Citation Envoyé par Foxaltex
    Code MATLAB : Sélectionner tout - Visualiser dans une fenêtre à part
    [-1 0 1; -2 0 2; 1 0 2]
    Cette matrice me semble douteuse.

    J'aurais pis :

    Code MATLAB : Sélectionner tout - Visualiser dans une fenêtre à part
    [-1 0 1; -2 0 2; -1 0 1]

    Pour ton autre question, quel est ta problématiques ?

    Cordialement.

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur vision
    Inscrit en
    Janvier 2013
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur vision
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2013
    Messages : 23
    Points : 29
    Points
    29
    Par défaut
    Bonjour,

    Oups... Je n'ai pas vu la faute de frappe. Je prends bien la matrice que tu indiques... Mais j'ai dû me tromper de touche.

    Pour ma problématique, l'image suivante devrait te faire comprendre :

    Nom : test_gris_02.jpg
Affichages : 1043
Taille : 40,8 Ko

    Un des coins de mon pentagone n'est pas détecté, ainsi qu'un des coins des flèches droite et gauche, du losange et de l'étoile. Ces coins non-détectés ont tous la même orientation. Je pense donc que mon algorithme passe à côté de quelque chose...

    Pour le calcul de mes coefficients de la matrice M, dois-je faire la moyenne des pixels dans ma fenêtre 3*3 ? Ou simplement la somme ?

    L'explication de Pseudo-code m'a beaucoup aidée (c.f. : http://xphilipp.developpez.com/artic...page_18#LXVIII ) merci à lui d'ailleurs, mais il est indiqué qu'il faut faire la moyenne des Ix², Iy² et Ixy... Et lorsque je fais cela, je ne trouve aucun coin haha.

    Je pense appliqué un Sobel "diagonal" type [-2, -1, 0; -1, 0, 1; 0, 1, 2] et la même chose dans l'autre diagonal. Qu'en penses-tu ?

    Je vais mettre le code de mon algo' (c++) dans l'après-midi, histoire que quelqu'un est une trace de ça.

    Merci de ton aide.

    Cordialement,

    Axel

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur vision
    Inscrit en
    Janvier 2013
    Messages
    23
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur vision
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2013
    Messages : 23
    Points : 29
    Points
    29
    Par défaut
    Bonjour à tous,

    Voici mon code :

    Code c++ : 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
     
    int HarrisFilter(Image* img_src, Image* img_dst, int Gauss, float k, int threshold, std::vector<Point> &corner_counter)
    {
        // basics verification
        if(img_src == NULL)    return -1;
        if(img_dst == NULL)    return -1;
        if(img_src->GetImageType() != 8)    return -1;
        if(img_dst->GetImageType() != 8)    return -1;
     
        // have dimension
        int width_src = img_src->GetWidth();
        int height_src = img_src->GetHeight();
        int ret = 5;
     
        // variables declaration
        Image* Ix_img        = new Image(width_src, height_src, 8, "X derivation");
        Image* Iy_img        = new Image(width_src, height_src, 8, "Y derivation");
     
        ret = SobelXY(img_src, Ix_img, Iy_img);
        if(ret == 0){
     
            // gaussian derivation
            if(Gauss > 0){
                GaussianSmooth(Ix_img, Ix_img, Gauss);
                GaussianSmooth(Iy_img, Iy_img, Gauss);
            }
     
            double A = 0, B = 0, C = 0;
            double responce = 2, harris_max = pow(255*255*9, responce);    // maximum value of compute harris responce
     
             Image* response_Harris = new Image(img_dst);
     
            // compute products of derivatives at each pixel and compute responce
            int y = 0, x = 0;
     
            // first line set to zero
            for(y=0; y<height_src; y++)
                response_Harris[y][0]= 0;
            for(x=1; x<width_src-1; x++) {
                // first column set to zero
                response_Harris[0][x]= 0;
                for(y=1; y<height_src-1; y++) {
                    /* H matrix, 2*2 : [ A = Sum(Ix²), B = Sum(Ixy),
                                     B = Sum(Ixy), C = Sum(Iy²) ] */
     
                    A =   Ix_img[y-1][x-1] * Ix_img[y-1][x-1] +   Ix_img[y-1][x  ] * Ix_img[y-1][x  ] +  Ix_img[y-1][x+1] * Ix_img[y-1][x+1] +
                          Ix_img[y  ][x-1] *  Ix_img[y  ][x-1] +   Ix_img[y  ][x  ] *   Ix_img[y  ][x  ] +   Ix_img[y  ][x+1] * Ix_img[y  ][x+1] + 
                          Ix_img[y+1][x-1] * Ix_img[y+1][x-1] + Ix_img[y+1][x  ] * Ix_img[y+1][x  ] + Ix_img[y+1][x+1] * Ix_img[y+1][x+1];
     
                    C =   Iy_img[y-1][x-1] * Iy_img[y-1][x-1] +  Iy_img[y-1][x  ] *  Iy_img[y-1][x  ] +   Iy_img[y-1][x+1] * Iy_img[y-1][x+1] +
                        Iy_img[y  ][x-1] * Iy_img[y  ][x-1] + Iy_img[y  ][x  ] * Iy_img[y  ][x  ] +    Iy_img[y  ][x+1] *  Iy_img[y  ][x+1] + 
                        Iy_img[y+1][x-1] * Iy_img[y+1][x-1] + Iy_img[y+1][x  ] * Iy_img[y+1][x  ] + Iy_img[y+1][x+1] * Iy_img[y+1][x+1];
     
                    B =   Ix_img[y-1][x-1] * Iy_img[y-1][x-1] +   Ix_img[y-1][x  ] * Iy_img[y-1][x  ] +   Ix_img[y-1][x+1] * Iy_img[y-1][x+1] +
                        Ix_img[y  ][x-1] *   Iy_img[y  ][x-1] +    Ix_img[y  ][x  ] *  Iy_img[y  ][x  ] +   Ix_img[y  ][x+1] *   Iy_img[y  ][x+1] + 
                        Ix_img[y+1][x-1] * Iy_img[y+1][x-1] + Ix_img[y+1][x  ] * Iy_img[y+1][x  ] + Ix_img[y+1][x+1] * Iy_img[y+1][x+1];
     
                    responce = (A * C - B * B) - k * (A + B) * (A + B);
     
                    if(responce > threshold){
                        responce *= (255/harris_max);
                        response_Harris[y][x] = responce;
                        response_Harris[y][x] = responce;
                    }else
                        response_Harris[y][x] = 0;
                }
                // last column set to zero
                response_Harris[height][x]= 0; 
            }
            // last line set to zero
            for(y=0; y<height_src; y++)
                response_Harris[y][width]= 0;
     
            ret = LocalMaxima(response_Harris, img_dst, 2);
            if(ret == 0){
                corner_counter.resize(0);
                // have corner count 
                for(int y=5; y<height_src-5;y++){
                    for(int x=5; x<width_src-5; x++){
                        if(img_dst[y][x] != 0){
                            corner_counter.push_back(x);
                            corner_counter.push_back(y);
                        }
                     }
                }
                int counter = corner_counter.size();
            }
        }
        // end 
        return 0;
    }

    Si vous pouvez me dire ce que vous en pensez... Ce serait sympa'.

    A+

    Foxaltex

Discussions similaires

  1. Détecteur de Harris - laplacien
    Par hanane78 dans le forum Images
    Réponses: 7
    Dernier message: 06/05/2013, 12h07
  2. [Image] Détecteur de Harris pour ImageJ
    Par pseudocode dans le forum Contribuez
    Réponses: 91
    Dernier message: 22/01/2013, 23h44
  3. Détecteur de Harris
    Par faroukus dans le forum OpenCV
    Réponses: 3
    Dernier message: 27/04/2008, 17h27
  4. Détecteur de Harris
    Par ninours23 dans le forum OpenCV
    Réponses: 6
    Dernier message: 01/02/2008, 23h53
  5. Détecteur de harris
    Par hanane78 dans le forum Images
    Réponses: 9
    Dernier message: 14/11/2007, 21h42

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