Marr Hildreth

1  /***********************************************************************************  
2      ImAnalyse : software in image processing and image analysis 
3     
4      Copyright (C) 10 juillet 2008  <Vincent MORARD> 
5    Version: 2.1 
6      Contact: vincent<POINT>morard<AROBAS>cpe<POINT>fr 
7    Website: http://ImAnalyse.free.fr 
8    Website: http://pistol.petesampras.free.fr 
9   
10      This program is free software: you can redistribute it and/or modify 
11      it under the terms of the GNU General Public License as published by 
12      the Free Software Foundation, either version 3 of the License, or 
13      (at your option) any later version. 
14   
15      This program is distributed in the hope that it will be useful, 
16      but WITHOUT ANY WARRANTY; without even the implied warranty of 
17      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
18      GNU General Public License for more details. 
19   
20      You should have received a copy of the GNU General Public License 
21      along with this program.  If not, see <http://www.gnu.org/licenses/ 
22  **********************************************************************************/ 
23  //****************************************************************************** 
24  //MarrHildreth   
25  //Cette fonction permet de calculer les contours suivant la méthode décrite par  
26  //Marr et Hildreth. Le principe est de calculer la derivée seconde de l'image et  
27  //de rechercher les zéros de cette image.  
28  //Pour ce faire, on calcule le laplacien de l'image. (Les dimensions de ce  
29  //filtre peuvent être changées suivant la valeur du paramètre d'entrée de  
30  //cette fonction.) Ce paramètre correspond à l'écart type du bruit. Plus s est  
31  //grand et plus le filtrage sera important. Il y aura donc moins de contours. 
32  //****************************************************************************** 
33  //************************************************************************* 
34  //Marr 
35  //On procède à tout le traitement dans cette fonction. 
36  //Calcul des coefficients du filtre Laplacian 
37  //convolution avec l'image initiale  
38  //et recherche des zéros de l'image obtenue  
39  //************************************************************************* 
40  #include "../CImage.h" 
41  #include "../AdvancEdge.h" 
42   
43  bool CImage::MarrHildreth(CImage *ImgDest,float S) 
44  { 
45    float **Img=0,s=(float)(S-0.8); 
46   
47   
48    int taille,i,j,n; 
49   
50    float **Lissage=0,**LGaussian=0; 
51   
52    if(hBmp==0){ 
53      MessageBox(NULL,"MarrHildreth : L'image source est vide", 
54        NULL,MB_OK|MB_ICONWARNING); 
55      return 0; 
56    } 
57   
58    if(ImgDest != 0 && ImgDest != this) 
59      ImgDest->Copy(this); 
60   
61   
62    if(ImgDest == 0) 
63      ImgDest=this; 
64    GetBitmapBits(hBmp,Width*Height*4,ucBits); 
65   
66   
67    //Création d'un filtre gaussien et d'un filtre correspondant à la dérivé d'un filtre 
68    //gaussien de taille 2*taille*1 
69    taille = (int)(3.35*s+0.33); 
70    n=2*taille+1; 
71   
72    LGaussian=AllocT_float(n,n); 
73   
74    //Création du masque avec la fonction LoG 
75    for(i=0;i<n;i++) 
76      for(j=0;j<n;j++) 
77        LGaussian[i][j]=LoG(Distance((float)i,(float)j,(float)taille,(float)taille),s); 
78   
79   
80    //Convolution de l'image initiale avec le masque en X et en Y 
81    Lissage=AllocT_float(Width,Height); 
82   
83    Convo(LGaussian,n,n,Lissage); 
84   
85   
86    //localisation des passages à zero 
87    ImgDest->ZeroCrossing(Lissage); 
88    SetBitmapBits(ImgDest->hBmp,Width*Height*4,ImgDest->ucBits); 
89   
90   
91    DesAllocT_float(Lissage,Width); 
92    DesAllocT_float(LGaussian,n); 
93   
94    return 1; 
95  } 
96   
97  //**************************************************************************** 
98  //ZeroCrossing 
99  //Cette fonction effectue la multiplication de deux pixels voisin et si le 
100  //résultat est négatif alors cela signifie qu'il y a eu un passage par zero. 
101  //**************************************************************************** 
102  void CImage::ZeroCrossing(float **Laplacian) 
103  { 
104   
105    int i,j; 
106   
107    for(i=1;i<Width-1;i++) 
108      for(j=1;j<Height-1;j++) 
109      { 
110        SetPixel(i,j,0,0,0); 
111        if(Laplacian[i-1][j]*Laplacian[i+1][j]<0) 
112        {SetPixel(i,j,255,255,255);continue;} 
113   
114        if(Laplacian[i][j-1]*Laplacian[i][j+1]<0) 
115        {SetPixel(i,j,255,255,255);continue;} 
116   
117        if(Laplacian[i+1][j-1]*Laplacian[i-1][j+1]<0) 
118        {SetPixel(i,j,255,255,255);continue;} 
119   
120        if(Laplacian[i-1][j-1]*Laplacian[i+1][j+1]<0) 
121        {SetPixel(i,j,255,255,255);continue;} 
122   
123      } 
124   
125   
126   
127  } 
128   
129  //*************************************************************************** 
130  //Convo 
131  //Convolution de l'image Img par le noyau Mask. Le resulat est stoker dans la  
132  //variable Res 
133  //*************************************************************************** 
134  void CImage::Convo(float **Mask,int MaskLargeur,int MaskHauteur,float **Res) 
135  { 
136    int i,j,k,l; 
137    float x; 
138    for(i=MaskLargeur/2;i<Width-MaskLargeur/2;i++) 
139      for(j=MaskHauteur/2;j<Height-MaskHauteur/2;j++) 
140      { 
141   
142        x=0.0; 
143        for(k=0;k<MaskLargeur;k++) 
144          for(l=0;l<MaskHauteur;l++) 
145            x+=Mask[k][l]*(float)GetPixel(i+k-MaskLargeur/2,j+l-MaskHauteur/2,GRAY); 
146   
147        Res[i][j]=x; 
148      } 
149   
150  } 
151   
152   
153  float LoG(float x, float Sigma) 
154  { 
155    float x1; 
156    x1=Gauss(x,Sigma); 
157    return (x*x-2*Sigma*Sigma)/(pow(Sigma,4)) *x1; 
158   
159  } 
160   
161  float Distance(float a, float b,float c,float d) 
162  { 
163    return Norm(a-c,b-d); 
164  } 

lien1 lien2 lien3