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

Images Discussion :

Algorithme de canny pour détection de contour


Sujet :

Images

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2006
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Algorithme de canny pour détection de contour
    Bonjour à vous amis programmeur,

    Je fais du traitement d'image et je désire faire une détection de contour à l'aide de l'algorithme de canny,
    Cela fais partie de mon travail de diplôme et le but final est de porter mon code sur DSP en C ou C++ donc fonction 'edge(img, 'canny')' de matlab interdite

    J'ai tout essayer, je fais des recherches depuis plusieurs jours cependant rien y fait je n'arrive pas à obtenir le même résultat que la fonction matlab.
    Je sais que des beaucoup de discussions traitent déjà du sujet sur ce forum comme sur beaucoup d'autre mais j'aimerais vos avis sur mes résultats si possible et une petite aide serait la bienvenue.

    J'ai appliqué selon moi l'algorithme rigoureusement suivant les directives de Wikipedia anglais et autres sources du net, mais rien à faire j'obtiens toujours des résultats différents. Voici ma méthode : (je donnerais mon code juste en dessous)

    - Filtrer l'image avec un filtre gaussien, (cf code, mais c'est du classique et jusque là pas de problème)
    - Appliquer une filtre de Sobel pour calculer le gradient ( j'approxime le gradient par le module de G_y + module de G_x, car je dois éviter les racines sur DSP)
    - Calcul de la direction du gradient, theta(y,x) = (180/pi)*atan2(G_y/G_x), puis arrondi à des multiples de 45°, entre 0 et 135
    - Calcul des maximum locaux en suivant la direction du gradient arrondi
    - Application d'un seuil avec hystérèses (j'ai bêtement pris les seuil t_min et t_max renvoyé par la fonction matlab pour l'instant)

    Et la 'BAM'!!!! J'ai beaucoup moins de contour que matlab

    Voici mon code suivis des résultats obtenus pour chaque étape presque. (et oui je vous met mon code complet)

    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
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
     
    %% Nettoyage
    clear all; close all; clc;
     
    %% Définitions
    TYPE = 'int32';
    img = imread('peppers.tif');
    img_ycbcr = rgb2ycbcr(img);
    img_Y   = int32(img_ycbcr(:,:,1));
    H = numel(img_Y(:,1));
    W = numel(img_Y(1,:));
     
    mat = 1/159*[2,4,5,4,2;4,9,12,9,4;5,12,15,12,5;4,9,12,9,4;2,4,5,4,2];
     
    % Filtrage de l'image de base afin de réduire le bruit de l'image
    img_f = my_Filter(img_Y, mat);
    %img_f = img_Y;
     
    % Balayage de l'image pour filtrage
    G_y     = zeros(size(img_Y), TYPE);
    G_x     = zeros(size(img_Y), TYPE);
    G       = zeros(size(img_Y), TYPE);
    G_max   = zeros(size(img_Y), TYPE);
    G_bin   = zeros(size(img_Y), TYPE);
    theta   = zeros(size(img_Y), TYPE);
    theta_p = zeros(size(img_Y), TYPE);
     
    for ind_y = 2 : H-1
        for ind_x = 2 : W-1
            % Filtre de Sobel
            % Application du filtre horozontal
            G_x(ind_y, ind_x) = (...
                                    +1*img_f(ind_y-1,ind_x-1) + 0*img_f(ind_y-1,ind_x) - 1*img_f(ind_y-1,ind_x+1) + ...
                                    +2*img_f(ind_y  ,ind_x-1) - 0*img_f(ind_y  ,ind_x) - 2*img_f(ind_y  ,ind_x+1) + ...
                                    +1*img_f(ind_y+1,ind_x-1) + 0*img_f(ind_y+1,ind_x) - 1*img_f(ind_y+1,ind_x+1) );
     
            % Application du filtre vertical
            G_y(ind_y, ind_x) = (...
                                    +1*img_f(ind_y-1,ind_x-1) + 2*img_f(ind_y-1,ind_x) + 1*img_f(ind_y-1,ind_x+1) + ...
                                     0*img_f(ind_y  ,ind_x-1) - 0*img_f(ind_y  ,ind_x) + 0*img_f(ind_y  ,ind_x+1) + ...
                                    -1*img_f(ind_y+1,ind_x-1) - 2*img_f(ind_y+1,ind_x) - 1*img_f(ind_y+1,ind_x+1) );                    
     
            % Calcul de l'angle du gradient
            theta(ind_y, ind_x) = (180/pi)*atan2(double(G_y(ind_y, ind_x)), double(G_x(ind_y, ind_x)));
     
            % Arrondi de l'angle pour obtenir une direction par palier de 45°
            if (theta(ind_y, ind_x)>=0-22.5 && theta(ind_y, ind_x)<0+22.5) ...
               || (theta(ind_y, ind_x)>=180-22.5 && theta(ind_y, ind_x)<-180+22.5)
                theta_p(ind_y, ind_x) = 0;
     
            elseif (theta(ind_y, ind_x)>=45-22.5 && theta(ind_y, ind_x)<45+22.5) ...
               || (theta(ind_y, ind_x)>=-135-22.5 && theta(ind_y, ind_x)<-135+22.5)
                theta_p(ind_y, ind_x) = 45;
     
            elseif (theta(ind_y, ind_x)>=90-22.5 && theta(ind_y, ind_x)<90+22.5) ...
               || (theta(ind_y, ind_x)>=-90-22.5 && theta(ind_y, ind_x)<-90+22.5)
                theta_p(ind_y, ind_x) = 90;
     
            elseif (theta(ind_y, ind_x)>=135-22.5 && theta(ind_y, ind_x)<135+22.5) ...
               || (theta(ind_y, ind_x)>=-45-22.5 && theta(ind_y, ind_x)<-45+22.5)
                theta_p(ind_y, ind_x) = 135;
     
            end
     
            % Module de G_x
            if G_x(ind_y, ind_x) < 0
                G_x(ind_y, ind_x) = -G_x(ind_y, ind_x);
            end
     
            % Module de G_y
            if G_y(ind_y, ind_x) < 0
                G_y(ind_y, ind_x) = -G_y(ind_y, ind_x);
            end
     
            % Calcul du gradient global
            G(ind_y, ind_x) = G_x(ind_y, ind_x) + G_y(ind_y, ind_x);
     
            %G(ind_y, ind_x) = sqrt(double(G_y(ind_y, ind_x)^2)+double(G_x(ind_y, ind_x)^2));
     
        end
    end
     
    % Recherche des maximum locaux (Thinning)
    G_max = G;  % Recopie pour Debug
    for ind_y = 2 : H-1
        for ind_x = 2 : W-1
            if theta_p(ind_y, ind_x) == 0
                if G(ind_y, ind_x)<G(ind_y, ind_x-1) || G(ind_y, ind_x)<G(ind_y, ind_x+1)
                    G_max(ind_y, ind_x) = 0;
                end
     
            elseif theta_p(ind_y, ind_x) == 45
                if G(ind_y, ind_x)<G(ind_y-1, ind_x-1) || G(ind_y, ind_x)<G(ind_y+1, ind_x+1)
                    G_max(ind_y, ind_x) = 0;
                end
     
            elseif theta_p(ind_y, ind_x) == 90
                if G(ind_y, ind_x)<G(ind_y-1, ind_x) || G(ind_y, ind_x)<G(ind_y+1, ind_x)
                    G_max(ind_y, ind_x) = 0;
                end
     
            elseif theta_p(ind_y, ind_x) == 135
                if G(ind_y, ind_x)<G(ind_y+1, ind_x-1) || G(ind_y, ind_x)<G(ind_y-1, ind_x+1)
                    G_max(ind_y, ind_x) = 0;
                end
     
            end
     
        end
    end
     
    % Seuillage pour binarisation
    max_G = max(max(G_max));
    t_low   = 0.0312*max_G;
    t_high  = 0.0781*max_G;
     
    for ind_y = 2+1 : H-2   % décallage de 2 car matrice 5x5 dans le cas incertain test2
        for ind_x = 2+1 : W-2
     
            if G_max(ind_y, ind_x) < t_low
                G_bin(ind_y, ind_x) = 0;
     
            elseif G_max(ind_y, ind_x) >= t_high
                G_bin(ind_y, ind_x) = 1;
     
            else
                % Recherche de valeur sup. à t_high dans ses 3x3 voisins
                if G_max(ind_y-1, ind_x-1)>=t_high || G_max(ind_y-1, ind_x)>=t_high || G_max(ind_y-1, ind_x+1)>=t_high || ...
                   G_max(ind_y  , ind_x-1)>=t_high ||                                  G_max(ind_y  , ind_x+1)>=t_high || ...
                   G_max(ind_y+1, ind_x-1)>=t_high || G_max(ind_y+1, ind_x)>=t_high || G_max(ind_y+1, ind_x+1)>=t_high
     
                    G_bin(ind_y, ind_x) = 1;
     
                elseif (G_max(ind_y-1, ind_x-1)>=t_low && G_max(ind_y-1, ind_x-1)<t_high) || ...
                       (G_max(ind_y-1, ind_x  )>=t_low && G_max(ind_y-1, ind_x  )<t_high) || ...
                       (G_max(ind_y-1, ind_x+1)>=t_low && G_max(ind_y-1, ind_x+1)<t_high) || ...
                       (G_max(ind_y  , ind_x-1)>=t_low && G_max(ind_y  , ind_x-1)<t_high) || ...
                       (G_max(ind_y  , ind_x+1)>=t_low && G_max(ind_y  , ind_x+1)<t_high) || ...
                       (G_max(ind_y+1, ind_x-1)>=t_low && G_max(ind_y+1, ind_x-1)<t_high) || ...
                       (G_max(ind_y+1, ind_x  )>=t_low && G_max(ind_y+1, ind_x  )<t_high) || ...
                       (G_max(ind_y+1, ind_x+1)>=t_low && G_max(ind_y+1, ind_x+1)<t_high)
     
                    % Si on est en zone incertaine ( t_low <= G < t_high)
                    % On test les voisins avec une matrice 5x5 (les voisins 3x3
                    % sont déjà testé.
                    if G_max(ind_y-2, ind_x-2)>=t_high || G_max(ind_y-2, ind_x-1)>=t_high || G_max(ind_y-2, ind_x)>=t_high || G_max(ind_y-2, ind_x+1)>=t_high || G_max(ind_y-2, ind_x+2)>=t_high || ...
                       G_max(ind_y-1, ind_x-2)>=t_high ||                                                                                                        G_max(ind_y-1, ind_x+2)>=t_high || ...
                       G_max(ind_y  , ind_x-2)>=t_high ||                                                                                                        G_max(ind_y  , ind_x+2)>=t_high || ...
                       G_max(ind_y+1, ind_x-2)>=t_high ||                                                                                                        G_max(ind_y+1, ind_x+2)>=t_high || ...
                       G_max(ind_y+2, ind_x-2)>=t_high || G_max(ind_y+2, ind_x-1)>=t_high || G_max(ind_y+2, ind_x)>=t_high || G_max(ind_y+2, ind_x+1)>=t_high || G_max(ind_y+2, ind_x+2)>=t_high
     
                        G_bin(ind_y, ind_x) = 1;
     
                    else
                        % Si aucun des 5x5 voisins n'est supérieur à t_high il
                        % ne s'agit pas d'un contour
                        G_bin(ind_y, ind_x) = 0;
     
                    end
     
                else
                    % Si on est inférieur à t_low il ne sagit pas d'un contour
                    G_bin(ind_y, ind_x) = 0;
     
                end
     
            end
        end
    end
     
    %% Affichage Canny
    figure;
    subplot(2,2,1);
    imshow(img_f, [min(min(img_f)) max(max(img_f))]);
    title('Image filtrée par un filtre passe bas');
    subplot(2,2,2);
    imshow(G, [min(min(G)) max(max(G))]);
    title('Gradient de l''image');
    subplot(2,2,3);
    imshow(G_max, [min(min(G_max)) max(max(G_max))]);
    title('Maximum du gradient (Thinning)');
    subplot(2,2,4);
    imshow(G_bin, [0 1]);
    title('Application d''un seuil avec Hysthérésis');
     
    %% Comparaison avec matlab
    figure;
    subplot(1,2,1);
    imshow(edge(double(img_f), 'canny'), [0 1]);
    title('Résultat Matlab');
    subplot(1,2,2);
    imshow(G_bin, [0 1]);
    title('Résultat à BIBI');
    Résultats obtenus pour les différentes étapes :
    Nom : canny_etape_par_etape.jpg
Affichages : 4741
Taille : 60,6 Ko

    Comparaison avec la fonction matlab (les seuils sont identiques):
    Nom : comparaison_canny_matlab_moi.jpg
Affichages : 4746
Taille : 127,2 Ko

    Vous voila au courant de mon désarrois à présent, j'espère ne pas vous avoir trop souler
    Si vous avez des idées sur mon erreur n'hésitez surtout pas à me contacter je vous en serais infiniment reconnaissant.

    PS : Le code a été écrit a but de portage sur un microcontrôleur, il a aussi été optimisé en tant que tel, donc oui la programmation matriciel n'est pas d'actualité et certains détails ont été optimisés pour la vitesse d’exécution (je pense entre autres à la recherche dans les voisins codée en dur)

    Merci d'avance pour vos réponses et le temps que vous m'avez accordé, et au plaisir de vous lire,

    André

  2. #2
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 32
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : Février 2014
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    bonjour monsieur


    Mais après l' application de code j'affiche cette erreur

    Undefined function 'my_Filter' for input arguments of type 'int32'.

Discussions similaires

  1. Algorithme d'évaluation pour détection de changement
    Par eviasra dans le forum Traitement d'images
    Réponses: 3
    Dernier message: 12/01/2012, 12h56
  2. algorithme d'octree pour détection de collision
    Par korsakoff69 dans le forum DirectX
    Réponses: 3
    Dernier message: 01/07/2010, 19h12
  3. Réponses: 7
    Dernier message: 15/07/2009, 22h47
  4. Algorithme de détection de contours
    Par winux32 dans le forum Traitement d'images
    Réponses: 9
    Dernier message: 10/10/2008, 18h51
  5. Réponses: 0
    Dernier message: 22/04/2008, 12h49

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