l'image de fond

fr       en

Traitements d'Images en Niveaux de Gris

Détection de lignes (Transformation de Hough)

Cette transformation va nous permettre de détecter les lignes d'une image. Cette transformation a besoin d'une image binaire. Chaque pixel de l'image binaire est représenté par une ligne dans l'espace de Hough. Regardez l'image suivante :
hough1
A gauche l'image d'origine avec un seul point à 1. A droite la transformation dans l'espace de Hough. On peut voir que le point à été transformé en ligne. regardons maintenant ce qui se passe pour plusieurs points appartenant à une même ligne.
hough2
On remarque que la transformation des pixels forme des lignes qui sont concourantes en un même point (dans le cercle rouge). Grâce à ce point, on peut retrouver la ligne qui passe par tous les points de l'image binaire.
hough3

Méthode

Nous commençons par faire une détection de contours sur une image originale. Le but est de transformer l'image en binaire et de détecter les lignes des contours. La taille de la matrice de transformation sera de la taille des lignes pour θ et de la taille de la diagonal de l'image pour rho. soit :
s i z e r h o = ( M 2 + N 2 ) 0.5
Où M est le nombre de lignes et N le nombre de colonnes. Cette matrice est initialisée à zéro. Maintenant pour chaque pixel de l'image qui est à 1 nous allons effectuer la transformation de hough. Chaque point représente une ligne dans l'espace de Hough, dans la matrice de transformation nous allons augmenter de 1 chaque point de la ligne. De ce fait, à chaque fois qu'une ligne passe par un point de la matrice, sa valeur croit. Plus il y a de ligne passant par un point plus celui-ci aura une importance. Le calcul qui nous permet de trouver les coordonnées dans la matrice de transformation à augmenter est :
à chaque point de l'image = 1 on fait pour θ de 0 à π
r h o = x . cos ( θ ) + y . sin ( θ )
Où x est la coordonnée du pixel en ligne et y la coordonnée en colonne. Grâce aux coordonnées (rho, θ ) on augmente la matrice de transformation.
une fois la transformation appliquée sur toute l'image nous trouvons un résultat qui peut ressembler à :
hough4
Il faut maintenant trouver les points qui ont de forts coefficients. Dans le programme, j'ai utilisé une technique de seuillage suivi par une détection des maxima locaux .

hough5
Maintenant que nous avons les coordonnées les plus importantes, il faut reconstruire les lignes. On a vu plus haut que chaque point de l'espace de hough donné une ligne dans l'espace x et y de l'image. La méthode consiste à calculer pour chaque pixel de l'image le résultat s'il correspond ou non à une ligne issue des coordonnées. dans chaque coordonnée nous avons un rho et un θ . On calcule pour chaque x et y tel que x=[1 M] et y=[1 N] :
r h o ' = x . cos ( θ ) + y . sin ( θ )
si r h o = r h o ' alors nous mettons la matrice résultat (x,y) à 1 sinon nous la laissons à 0.

Programme

function guihoug
clear all;
close all;
figure(  'Name','translation',...
            'NumberTitle','off',...
            'color',[0.3137 0.3137 0.5098]);
       
a(1)=axes('units','normalized',...
    'position',[0.05 0.55 0.35 0.35]);
a(2)=axes('units','normalized',...
    'position',[0.5 0.55 0.35 0.35]);
a(3)=axes('units','normalized',...
    'position',[0.05 0.1 0.35 0.35]);
a(4)=axes('units','normalized',...
    'position',[0.5 0.1 0.35 0.35]);
uicontrol(  'style','pushbutton',...
            'string','load',...
            'Position', [10 10 50 20],...
            'callback',@loadimage);
       
uicontrol(  'style','pushbutton',...
            'string','executer',...
            'Position', [290 10 100 20],...
            'callback',@executer);
uicontrol(  'style','edit',...
            'string','10',...
            'Position', [180 10 50 20],...
            'callback',{@nbline,'nline'});
text(1)=uicontrol(  'style','text',...
            'string','number of line: ',...
            'Position', [80 10 100 20]);
%parametre initial
setappdata(gcf,'x',1);
setappdata(gcf,'type',0);
setappdata(gcf,'nline',10);

     
function loadimage(~,~)
    % appeler quand appui check box
    [filename, pathname] = uigetfile({'*.jpg;*.tif;*.png;*.gif;*.bmp','All Image Files';...
          '*.*','All Files' },'mytitle',...
          'C:\Work\myfile.jpg')

    x = imread(filename);
    if (length(size(x))>2)
        x=x(:,:,1);% on prend une seul plan image noir et blanc chaque plan sont egaux
    end
    k = whos('x');
    if k.class == 'uint8'
        k=8;
    end
    setappdata(1,'k',k);
    setappdata(1,'x',x);
    axes(a(1))
    imshow(x)
    title('original image')

   
end
function executer(hObj,~,Name)

     type = getappdata(1,'type');
     img = getappdata(1,'x');
     nline = getappdata(1,'nline');
     [ligne colonne]=size(img);
     centreligne = round(ligne/2);
     centrecolonne = round(colonne/2);
     img=double(img);
     
     
     %détection de contour
     %edge detection
     %imgedge = edge(img,'canny');prewitt
     imgedge = edge(img,'prewitt');
     axes(a(2))
     imshow(imgedge)
     title('edge detection')
     %
     
     theta_step = pi/(ligne);
     r_max = ceil(((ligne^2 + colonne^2)^0.5 / 2)) ;
     A=zeros(ligne,r_max*2+1);%A(theta, r)
     for i = 1 : ligne
         for j = 1 : colonne
             if (imgedge(i,j))==1
                 x=i-centreligne;
                 y=j-centrecolonne;
                 %p=1;
                 for t = 1 : ligne
                     theta = t * theta_step;
                     r = r_max  + 1+round(x * cos(theta) + y * sin(theta));
                    % h(p)=r;
                     A(t,r)= A(t,r) + 1;
                     %p=p+1
                 end  
             end
         end
     end
     
     axes(a(3))
     imshow(uint8(-(A-max(max(A))*(255/max(max(A))))))
     title('hough tranformation')
     threshold = max(max(A))*0.4;
     A(A<threshold)=0;
     A = wextend(2,'zpd',A,2);
     for i = 3 : size(A,1)-3
         for j = 3 : size(A,2)-3
             maxi=max(max(A(i-2:i+2,j-2:j+2)));
             if A(i,j)~=maxi
                A(i,j)=0;
             end
         end
     end
     A=A(3:end-2,3:end-2);
     %A(A>0)=1;
         
     maxlocaux=[]; %[theta r]
     p=1;
     for i = 1 : size(A,1)
         for j = 1 : size(A,2)
             if A(i,j) ~=0
                 maxlocaux(p,:)=[i,j,A(i,j)];
                 p=p+1;
             end
         end
     end
     
     %sort
     [value tri] = sort(maxlocaux(:,3),1,'descend');
     if nline>length(maxlocaux(:,3));
         nline = length(maxlocaux(:,3));
     end
     for i = 1 : nline
             maxlocauxsort(i,:)=maxlocaux(tri(i),1:2);
     end
     
     
     img2=zeros(ligne,colonne);
     for p = 1 : length(maxlocauxsort)
         pointH=maxlocauxsort(p,:);
         for i = 1 : ligne
             for j = 1 : colonne
                 x=i-centreligne;
                 y=j-centrecolonne;
                 %r = r_max  + 1+round( i* cos(-pointH(1)*theta_step) + j * sin(-pointH(1)*theta_step))
                 r = r_max  + 1+round( x* cos(pointH(1)*theta_step) + y * sin(pointH(1)*theta_step));
                 if r == pointH(2)
                     img2(i,j)=1;
                 end
             end
         end
         
     end
     
     
     axes(a(4))
     imshow(img2)
     title('line')
     figure
     imshow(img2)
     
end
function nbline(hObj,~,Name)
    % Called when user activates popup menu
    val = str2num(get(hObj,'String')); %0|1=ligne, 2=colonne, 3=croix, 4=carre
    setappdata(1,Name,val);
end
end

Exemple


hough6

Copyright © 2010-2014, tous droits réservés, contact : operationpixel@free.fr