Median_cpp

1  /***********************************************************************************  
2      ImAnalyse : software in image processing and image analysis 
3     
4      Copyright (C) 27 avril 2008  <Vincent MORARD> 
5    Version: 2.0 
6      Contact: vincent<POINT>morard<AROBAS>cpe<POINT>fr 
7    Website: http://pistol.petesampras.free.fr 
8   
9      This program is free software: you can redistribute it and/or modify 
10      it under the terms of the GNU General Public License as published by 
11      the Free Software Foundation, either version 3 of the License, or 
12      (at your option) any later version. 
13   
14      This program is distributed in the hope that it will be useful, 
15      but WITHOUT ANY WARRANTY; without even the implied warranty of 
16      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
17      GNU General Public License for more details. 
18   
19      You should have received a copy of the GNU General Public License 
20      along with this program.  If not, see <http://www.gnu.org/licenses/ 
21  **********************************************************************************/ 
22  #include "../CImage.h" 
23   
24  int Tri(int *t,int Size,int NumPixel) 
25  { 
26   
27    int i,j; 
28    int tmp = 0; 
29    bool en_desordre = TRUE; 
30   
31    for(i = 0 ; (i < Size) && en_desordre; i++) 
32    { 
33      en_desordre = FALSE; 
34      for(j = 1 ; j < Size - i ; j++) 
35      { 
36        if(t[j] < t[j-1]) 
37        { 
38          tmp = t[j-1]; 
39          t[j-1] = t[j]; 
40          t[j] = tmp; 
41          en_desordre = TRUE; 
42        } 
43      } 
44    } 
45    return t[NumPixel]; 
46  } 
47  double Tri(double *t,int Size,int NumPixel) 
48  { 
49   
50    int i,j; 
51    double tmp = 0; 
52    bool en_desordre = TRUE; 
53   
54    for(i = 0 ; (i < Size) && en_desordre; i++) 
55    { 
56      en_desordre = FALSE; 
57      for(j = 1 ; j < Size - i ; j++) 
58      { 
59        if(t[j] < t[j-1]) 
60        { 
61          tmp = t[j-1]; 
62          t[j-1] = t[j]; 
63          t[j] = tmp; 
64          en_desordre = TRUE; 
65        } 
66      } 
67    } 
68    return t[NumPixel]; 
69  } 
70   
71   
72  bool CImage::Median(int Type,int n,int Pourcentage,CImage *ImgDest) 
73  { 
74    if(hBmp==0){ 
75      MessageBox(NULL,"Median : L'image source est vide", 
76        NULL,MB_OK|MB_ICONWARNING); 
77      return 0; 
78    } 
79    int NumPixel = n*n*Pourcentage/100; 
80    if(NumPixel<0 ||NumPixel > n*n){ 
81      MessageBox(NULL,"Median : On doit recuperer le ième pixel: i compris entre 1 et 9", 
82        NULL,MB_OK|MB_ICONWARNING); 
83      return 0; 
84    } 
85    if(n!=3 && n!=5 && n!=7 && n!=9 && n!=11 && n!=13 && n!=15){ 
86      MessageBox(NULL,"Median : Taille du noyau invalide", 
87        NULL,MB_OK|MB_ICONWARNING); 
88      return 0; 
89    } 
90   
91    if(ImgDest!=0 && ImgDest!=this) 
92      ImgDest->Copy(this); 
93    if(ImgDest==0) 
94      ImgDest=this; 
95   
96    int i,j,k,l,*Tab; 
97    Tab=new int[n*n]; 
98   
99   
100   
101    double *MED=new double[Width*Height]; 
102   
103   
104    double *MED_Red,*MED_Green; 
105    if(Type==RGBi) 
106    { 
107      MED_Red=new double[Width*Height]; 
108      MED_Green=new double[Width*Height]; 
109    } 
110   
111    //recupération des pixels 
112    GetBitmapBits(hBmp,Width*Height*4,ucBits); 
113   
114    for(i=n/2;i<Width-n/2;i++) 
115      for(j=n/2;j<Height-n/2;j++) 
116      { 
117        switch(Type) 
118        { 
119        case RGBi: 
120          for(k=-n/2;k<=n/2;k++) 
121            for(l=-n/2;l<=n/2;l++) 
122              Tab[l+n/2+(k+n/2)*n]=(int)GetPixel(i+k,j+l,RED); 
123          MED_Red[(i+j*Width)]=Tri(Tab,n*n,NumPixel); 
124   
125          for(k=-n/2;k<=n/2;k++) 
126            for(l=-n/2;l<=n/2;l++) 
127              Tab[l+n/2+(k+n/2)*n]=(int)GetPixel(i+k,j+l,GREEN); 
128          MED_Green[(i+j*Width)]=Tri(Tab,n*n,NumPixel); 
129   
130          for(k=-n/2;k<=n/2;k++) 
131            for(l=-n/2;l<=n/2;l++) 
132              Tab[l+n/2+(k+n/2)*n]=(int)GetPixel(i+k,j+l,BLUE); 
133          MED[(i+j*Width)]=Tri(Tab,n*n,NumPixel); 
134   
135   
136          break; 
137        default: 
138          for(k=-n/2;k<=n/2;k++) 
139            for(l=-n/2;l<=n/2;l++) 
140              Tab[l+n/2+(k+n/2)*n]=(int)GetPixel(i+k,j+l,Type); 
141          MED[(i+j*Width)]=Tri(Tab,n*n,NumPixel); 
142          break; 
143        } 
144      } 
145   
146      switch(Type) 
147      { 
148      case RGBi: 
149        ImgDest->ImgType=RGBi; 
150        for(i=0,j=0;i<Width*Height*4;i+=4,j++) 
151        { 
152          ImgDest->ucBits[i]=(UCHAR)MED[j]; 
153          ImgDest->ucBits[i+1]=(UCHAR)MED_Green[j]; 
154          ImgDest->ucBits[i+2]=(UCHAR)MED_Red[j]; 
155   
156        } 
157        delete []MED_Red; 
158        delete []MED_Green; 
159   
160        break; 
161   
162      default: 
163        ImgDest->ImgType=GRAY; 
164        for(i=0,j=0;i<Width*Height*4;i+=4,j++) 
165        { 
166          ImgDest->ucBits[i]=(UCHAR)MED[j]; 
167          ImgDest->ucBits[i+1]=ImgDest->ucBits[i]; 
168          ImgDest->ucBits[i+2]=ImgDest->ucBits[i]; 
169   
170        } 
171        break; 
172   
173   
174      } 
175   
176      delete []MED; 
177      delete []Tab; 
178   
179      SetBitmapBits (ImgDest->hBmp,(Width*Height)*4,ImgDest->ucBits); 
180   
181      return 1; 
182  } 
183   
184   
185   
186  bool CImage::MedianHSL(int n,int Pourcentage,CImage *ImgDest) 
187  { 
188   
189   
190    if(hBmp==0){ 
191      MessageBox(NULL,"MedianHSL : L'image source est vide", 
192        NULL,MB_OK|MB_ICONWARNING); 
193      return 0; 
194    } 
195    if(ImgType != RGBi){ 
196      MessageBox(NULL,"MedianHSL : L'image doit etre une image couleur", 
197        NULL,MB_OK|MB_ICONWARNING); 
198      return 0; 
199    } 
200   
201    int NumPixel = n*n*Pourcentage/100; 
202    if(NumPixel<0 ||NumPixel > n*n){ 
203      MessageBox(NULL,"Median HSL: On doit recuperer le ième pixel: i compris entre 1 et 9", 
204        NULL,MB_OK|MB_ICONWARNING); 
205      return 0; 
206    } 
207    if(n!=3 && n!=5 && n!=7 && n!=9 && n!=11 && n!=13 && n!=15){ 
208      MessageBox(NULL,"Median HSL: Taille du noyau invalide", 
209        NULL,MB_OK|MB_ICONWARNING); 
210      return 0; 
211    } 
212   
213    if(ImgDest!=0 && ImgDest!=this) 
214      ImgDest->Copy(this); 
215    if(ImgDest==0) 
216      ImgDest=this; 
217   
218    int i,j,k,l; 
219    double *Tab; 
220   
221    Tab=new double[n*n]; 
222    double *HSL=this->RGB_to_HSL(); 
223   
224    if(HSL==0 || Tab==0){ 
225      MessageBox(NULL,"Median HSL: Erreur allocation", 
226        NULL,MB_OK|MB_ICONWARNING); 
227      return 0; 
228    } 
229    //recupération des pixels 
230    GetBitmapBits(hBmp,Width*Height*4,ucBits); 
231   
232    for(i=n/2;i<Width-n/2;i++) { 
233      for(j=n/2;j<Height-n/2;j++) 
234      { 
235        for(k=-n/2;k<=n/2;k++) 
236          for(l=-n/2;l<=n/2;l++) 
237            Tab[l+n/2+(k+n/2)*n]=(int)HSL[4*(i+k+(j+l)*Width)+2]; 
238   
239        HSL[4*(i+j*Width)+2]=Tri(Tab,n*n,NumPixel); 
240   
241   
242      } 
243    } 
244   
245   
246    ImgDest->HSL_to_RGB(HSL,n/2); 
247   
248   
249    delete []Tab; 
250    delete []HSL; 
251    SetBitmapBits (ImgDest->hBmp,(Width*Height)*4,ImgDest->ucBits); 
252   
253    return 1; 
254  } 
255  double Abs(double x)  {return ((x<0)?(-x):(x));} 
256   
257  void RGB_to_HSL2(double R,double G,double B,double *H,double *S,double *L) 
258  { 
259    //Normalisation 
260    R/=255;G/=255;B/=255; 
261   
262    double Min=min(R,min(G,B)); 
263    double Max=max(R,max(G,B)); 
264   
265    *L=(Min+Max)/2; 
266   
267    if(Abs(Max-Min) < 0.000001) {  //achromatic 
268      *H=0;*S=0; 
269    } 
270    else 
271    { 
272      double Delta=Max-Min; 
273      *S = (( *L > 0.5 ) ? ( Delta/(2-Min-Max )) : (Delta/(Max+Min))); 
274   
275      if(Abs(R-Max)<0.000001) 
276        *H = (G - B) / Delta + (G < B ? 6 : 0); 
277      else if(Abs(G-Max)<0.000001) 
278        *H = (B - R) / Delta + 2; 
279      else if(Abs(B-Max)<0.000001) 
280        *H = (R - G) / Delta + 4; 
281      *H/=6; 
282    } 
283    *H *= 240; 
284    *S *= 240; 
285    *L *= 240; 
286  } 
287   
288  double Hue_2_RGB(double v1,double v2,double vH )             //Function Hue_2_RGB 
289  { 
290     if ( vH < 0 ) vH += 1; 
291     if ( vH > 1 ) vH -= 1; 
292     if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH ); 
293     if ( ( 2 * vH ) < 1 ) return ( v2 ); 
294     if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * ( ( 0.666666 ) - vH ) * 6 ); 
295     return v1; 
296  } 
297   
298   
299  void HSL_to_RGB2(double H,double  S,double L,double *R,double *G,double*B) 
300  { 
301    double tmp1,tmp2; 
302    H=(double)H/239;      //h,s,l compris entre 0 et 1 
303    S=(double)S/240; 
304    L=(double)L/240; 
305   
306    if(S==0) 
307    { 
308      *R = 255 * L; 
309      *G = 255 * L; 
310      *B = 255 * L; 
311    } 
312    else 
313    { 
314      if(L<0.5)tmp2 = L * (1 + S); 
315      else tmp2 = (L + S) - (L * S); 
316      tmp1=2 * L - tmp2; 
317   
318      *R = 255 * Hue_2_RGB( tmp1, tmp2, H + ( 0.333333 ) ); 
319      *G = 255 * Hue_2_RGB( tmp1, tmp2, H ); 
320        *B = 255 * Hue_2_RGB( tmp1, tmp2, H - ( 0.333333) ); 
321   
322    } 
323  } 
324   
325   
326   
327   
328  double *CImage::RGB_to_HSL() 
329  { 
330    double *Tab=0; 
331    int i; 
332    double H,S,L; 
333    Tab=new double[Width*Height*4]; 
334    if(Tab==0)return NULL; 
335   
336    //recupération des pixels 
337    GetBitmapBits(hBmp,Width*Height*4,ucBits); 
338   
339    for(i=0;i<Width*Height*4;i+=4) 
340    { 
341      RGB_to_HSL2((double)ucBits[i+2],(double)ucBits[i+1],(double)ucBits[i],&H,&S,&L); 
342      Tab[i]=H; 
343      Tab[i+1]=S; 
344      Tab[i+2]=L; 
345   
346    } 
347    return Tab; 
348   
349  } 
350   
351   
352   
353   
354  void CImage::HSL_to_RGB(double *HSL,int Boundaries) 
355  { 
356    int i,j,Pos; 
357    double R,G,B; 
358   
359   
360    for(i=Boundaries;i<Width-Boundaries;i++) { 
361      for(j=Boundaries;j<Height-Boundaries;j++) 
362      { 
363        Pos=4*(i+j*Width); 
364        HSL_to_RGB2(HSL[Pos],HSL[Pos+1],HSL[Pos+2],&R,&G,&B); 
365        ucBits[i]=(UCHAR)B; 
366        ucBits[i+1]=(UCHAR)G; 
367        ucBits[i+2]=(UCHAR)R; 
368   
369      } 
370    } 
371  } 
372   
373   
374  //http://mjijackson.com/2008/02/10/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript/ 

lien1 lien2 lien3