KangWang.cpp

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  #include "../CImage.h" 
24  #include "../AdvancEdge.h" 
25   
26  double w1=90; 
27  double w2=40; 
28   
29   
30  float MIN(float x,float y){return (x<y ? x : y);} 
31  float ABS(float x){return (x<0 ? (-x) : (x));} 
32   
33   
34  bool CImage::KangWang(CImage *ImgDest,int Seuil) 
35  { 
36   
37    float **E=0; 
38    int **Direction=0; 
39   
40    if(hBmp==0){ 
41      MessageBox(NULL,"KangWang : L'image source est vide", 
42        NULL,MB_OK|MB_ICONWARNING); 
43      return 0; 
44    } 
45   
46    if(ImgDest != 0 && ImgDest != this) 
47      ImgDest->Copy(this); 
48   
49    if(ImgDest == 0) 
50      ImgDest=this; 
51   
52   
53   
54    GetBitmapBits(hBmp,Width*Height*4,ucBits); 
55   
56    //Allocation dynamique des images 
57    E=AllocT_float(Width,Height); 
58    Direction=AllocT_int(Width,Height); 
59   
60    this->KW_Convolution(E,Direction); 
61   
62    ImgDest->KW_NonMaxSuppress(Seuil,E,Direction); 
63    ImgDest->ImgType=GRAY; 
64   
65    SetBitmapBits(ImgDest->hBmp,Width*Height*4,ImgDest->ucBits); 
66   
67    DesAllocT_int(Direction,Width); 
68    DesAllocT_float(E,Width); 
69    return 1; 
70   
71  } 
72   
73  void CImage::KW_Convolution(float **E,int **Direction) 
74  { 
75    int i,j,k,l; 
76    float E_[4],Max; 
77    BYTE Voisin[9]; 
78    for(i=1;i<Width-1;i++) 
79      for(j=1;j<Height-1;j++) 
80      { 
81   
82        for(k=-1;k<=1;k++) 
83          for(l=-1;l<=1;l++) 
84            Voisin[(k+1)+(l+1)*3]=(BYTE)GetPixel(i+k,j+l,GRAY); 
85   
86        for(k=0;k<4;k++) 
87          E_[k]=ObjectiveFunction(k,Voisin); 
88   
89        Max=E_[0]; 
90        Direction[i][j]=0; 
91        for(k=1;k<4;k++) 
92          if(E_[k]>Max) 
93          { 
94            Max=E_[k]; 
95            Direction[i][j]=k; 
96          } 
97          E[i][j]=Max; 
98      } 
99  } 
100   
101  float ObjectiveFunction(int Direction,BYTE *Voisin) 
102  { 
103    float Nf,Df,m1,m0; 
104    BYTE S0[6],S1[3]; 
105    int i,j,S1indice=0,S0indice=0; 
106    for(i=0;i<3;i++) 
107      for(j=0;j<3;j++) 
108      { 
109        switch(Direction) 
110        { 
111        case 0:      //Direction horizontale 
112          if(i==0 || i==1) 
113            S0[S0indice++]=Voisin[i+3*j];else S1[S1indice++]=Voisin[i+3*j]; 
114          break; 
115   
116        case 1:      //Direction Verticale 
117          if(j==0 || j==1) 
118            S0[S0indice++]=Voisin[i+3*j];else S1[S1indice++]=Voisin[i+3*j]; 
119          break; 
120   
121        case 2:      //Direction Diagonale1 
122          if((i==2 && j>=1)|| (j==2 && i==1)) 
123            S1[S1indice++]=Voisin[i+3*j];else S0[S0indice++]=Voisin[i+3*j]; 
124          break; 
125   
126        case 3:      //Direction Diagonale2 
127          if((i==0 && j>=1)|| (j==2 && i==1)) 
128            S1[S1indice++]=Voisin[i+3*j];else S0[S0indice++]=Voisin[i+3*j]; 
129          break; 
130        } 
131      } 
132   
133      m0=(float)(S0[0]+S0[1]+S0[2]+S0[3]+S0[4]+S0[5])/6; 
134      m1=(float)(S1[0]+S1[1]+S1[2])/3; 
135   
136      Nf=MIN((float)1.0,(float)(ABS(m0-m1)/(float)w1)); 
137   
138      m0=0;m1=0; 
139      for(i=0;i<6;i++) 
140        for(j=0;j<6;j++) 
141          if(i!=j && i>j) 
142            m0+=MIN((float)1.0,ABS((float)S0[i]-(float)S0[j])/(float)w2); 
143   
144      for(i=0;i<3;i++) 
145        for(j=0;j<3;j++) 
146          if(i!=j && i>j) 
147            m1+=MIN((float)1.0,ABS((float)S1[i]-(float)S1[j])/(float)w2); 
148   
149      Df=(float)(1.0+m0/15.0+m1/3.0); 
150   
151      return 255*(float)(Nf/Df); 
152   
153  } 
154   
155   
156  void CImage::KW_NonMaxSuppress(int Seuil,float **E,int **Direction) 
157  { 
158    int i,j; 
159   
160   
161   
162    for(i=1;i<Width-1;i++) 
163      for(j=1;j<Height-1;j++) 
164      { 
165        SetPixel(i,j,0,0,0); 
166        if(E[i][j]>Seuil) 
167        { 
168          switch(Direction[i][j]) 
169          { 
170          case 0: 
171            if(E[i][j]>=E[i][j-1] && E[i][j]>=E[i][j+1]) 
172              SetPixel(i,j,255,255,255); 
173            break; 
174   
175          case 1: 
176            if(E[i][j]>=E[i-1][j] && E[i][j]>=E[i+1][j]) 
177              SetPixel(i,j,255,255,255); 
178            break; 
179   
180          case 2: 
181            if(E[i][j]>=E[i-1][j+1] && E[i][j]>=E[i+1][j-1]) 
182              SetPixel(i,j,255,255,255); 
183            break; 
184   
185          case 3: 
186            if(E[i][j]>=E[i-1][j-1] && E[i][j]>=E[i+1][j+1]) 
187              SetPixel(i,j,255,255,255); 
188            break; 
189          } 
190        } 
191   
192      } 
193   
194  } 

lien1 lien2 lien3