Prewitt

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  #include "../CImage.h" 
25   
26   
27   
28   
29   
30  //Worker Threads 
31  //Chacun des threads a une partie de l'image a traiter et se termine lorsqu'il a fini sa zone 
32  DWORD WINAPI PREWITT(LPVOID lParam) 
33  { 
34    MULTITHREAD *MT=(MULTITHREAD*)lParam; 
35    MT->Error=0; 
36    if(MT->ImgDest==0 || MT->ImgDest->GetHBmp()==0){ 
37      MT->Error=1; 
38      return 0; 
39    } 
40    int i,j,Pos; 
41    double Gx,Gy; 
42    Dimension Dim=MT->ImgDest->GetDimension(); 
43   
44    if(MT->Param1!=RGBi) 
45      MT->ImgDest->SetType(GRAY); 
46   
47    for(i=MT->X0 ; i<MT->X1 ; i++) 
48      for(j=MT->Y0 ; j<MT->Y1 ; j++) 
49      { 
50   
51        Pos=( i+ j * Dim.cx)*4; 
52   
53        if(i==0 || i==Dim.cx-1 ||j==0 || j==Dim.cy-1) 
54        { 
55   
56          MT->ImgDest->ucBits[Pos+2]=0; 
57          MT->ImgDest->ucBits[Pos+1]=0; 
58          MT->ImgDest->ucBits[Pos+2]=0; 
59          continue; 
60        } 
61        switch(MT->Param1) 
62        { 
63        case RGBi : 
64   
65            Gx=  MT->ucBits[(i-1+(j-1)*Dim.cx)*4] + MT->ucBits[(i+(j-1)*Dim.cx)*4] + MT->ucBits[(i+1+(j-1)*Dim.cx)*4] 
66               -MT->ucBits[(i-1+(j+1)*Dim.cx)*4] - MT->ucBits[(i+(j+1)*Dim.cx)*4] - MT->ucBits[(i+1+(j+1)*Dim.cx)*4]; 
67            Gy=  MT->ucBits[(i-1+(j-1)*Dim.cx)*4] + MT->ucBits[(i-1+j*Dim.cx)*4] + MT->ucBits[(i-1+(j+1)*Dim.cx)*4] 
68               -MT->ucBits[(i+1+(j+1)*Dim.cx)*4] - MT->ucBits[(i+1+j*Dim.cx)*4] - MT->ucBits[(i+1+(j+1)*Dim.cx)*4]; 
69            MT->ImgDest->ucBits[Pos]=(int)Limit(sqrt(Gx*Gx+Gy*Gy)); 
70   
71            Gx=  MT->ucBits[(i-1+(j-1)*Dim.cx)*4+1] + MT->ucBits[(i+(j-1)*Dim.cx)*4+1] + MT->ucBits[(i+1+(j-1)*Dim.cx)*4+1] 
72               -MT->ucBits[(i-1+(j+1)*Dim.cx)*4+1] - MT->ucBits[(i+(j+1)*Dim.cx)*4+1] - MT->ucBits[(i+1+(j+1)*Dim.cx)*4+1]; 
73            Gy=  MT->ucBits[(i-1+(j-1)*Dim.cx)*4+1] + MT->ucBits[(i-1+j*Dim.cx)*4+1] + MT->ucBits[(i-1+(j+1)*Dim.cx)*4+1] 
74               -MT->ucBits[(i+1+(j+1)*Dim.cx)*4+1] - MT->ucBits[(i+1+j*Dim.cx)*4+1] - MT->ucBits[(i+1+(j+1)*Dim.cx)*4+1]; 
75            MT->ImgDest->ucBits[Pos+1]=(int)Limit(sqrt(Gx*Gx+Gy*Gy)); 
76   
77            Gx=  MT->ucBits[(i-1+(j-1)*Dim.cx)*4+2] + MT->ucBits[(i+(j-1)*Dim.cx)*4+2] + MT->ucBits[(i+1+(j-1)*Dim.cx)*4+2] 
78               -MT->ucBits[(i-1+(j+1)*Dim.cx)*4+2] - MT->ucBits[(i+(j+1)*Dim.cx)*4+2] - MT->ucBits[(i+1+(j+1)*Dim.cx)*4+2]; 
79            Gy=  MT->ucBits[(i-1+(j-1)*Dim.cx)*4+2] + MT->ucBits[(i-1+j*Dim.cx)*4+2] + MT->ucBits[(i-1+(j+1)*Dim.cx)*4+2] 
80               -MT->ucBits[(i+1+(j+1)*Dim.cx)*4+2] - MT->ucBits[(i+1+j*Dim.cx)*4+2] - MT->ucBits[(i+1+(j+1)*Dim.cx)*4+2]; 
81            MT->ImgDest->ucBits[Pos+2]=(int)Limit(sqrt(Gx*Gx+Gy*Gy)); 
82            break; 
83   
84          case GRAY : 
85            double D[8]; 
86   
87            D[0]=(MT->ucBits[(i-1+(j-1)*Dim.cx)*4]+MT->ucBits[(i-1+(j-1)*Dim.cx)*4+1]+MT->ucBits[(i-1+(j-1)*Dim.cx)*4+2])/3; 
88            D[1]=(MT->ucBits[(i+(j-1)*Dim.cx)*4]+MT->ucBits[(i+(j-1)*Dim.cx)*4+1]+MT->ucBits[(i+(j-1)*Dim.cx)*4+2])/3; 
89            D[2]=(MT->ucBits[(i+1+(j-1)*Dim.cx)*4]+MT->ucBits[(i+1+(j-1)*Dim.cx)*4+1]+MT->ucBits[(i+1+(j-1)*Dim.cx)*4+2])/3; 
90   
91            D[3]=(MT->ucBits[(i-1+j*Dim.cx)*4]+MT->ucBits[(i-1+j*Dim.cx)*4+1]+MT->ucBits[(i-1+j*Dim.cx)*4+2])/3; 
92            D[4]=(MT->ucBits[(i+1+j*Dim.cx)*4]+MT->ucBits[(i+1+j*Dim.cx)*4+1]+MT->ucBits[(i+1+j*Dim.cx)*4+2])/3; 
93   
94            D[5]=(MT->ucBits[(i-1+(j+1)*Dim.cx)*4]+MT->ucBits[(i-1+(j+1)*Dim.cx)*4+1]+MT->ucBits[(i-1+(j+1)*Dim.cx)*4+2])/3; 
95            D[6]=(MT->ucBits[(i+(j+1)*Dim.cx)*4]+MT->ucBits[(i+(j+1)*Dim.cx)*4+1]+MT->ucBits[(i+(j+1)*Dim.cx)*4+2])/3; 
96            D[7]=(MT->ucBits[(i+1+(j+1)*Dim.cx)*4]+MT->ucBits[(i+1+(j+1)*Dim.cx)*4+1]+MT->ucBits[(i+1+(j+1)*Dim.cx)*4+2])/3; 
97   
98            Gx=D[0]+D[1]+D[2]-D[5]-D[6]-D[7]; 
99            Gy=D[0]+D[3]+D[5]-D[2]-D[4]-D[7]; 
100   
101            MT->ImgDest->ucBits[Pos]=  (int)Limit(sqrt(Gx*Gx+Gy*Gy)); 
102            MT->ImgDest->ucBits[Pos+1]=MT->ImgDest->ucBits[Pos]; 
103            MT->ImgDest->ucBits[Pos+2]=MT->ImgDest->ucBits[Pos]; 
104   
105            break; 
106   
107          case RED  : 
108            Gx=  MT->ucBits[(i-1+(j-1)*Dim.cx)*4+2] + MT->ucBits[(i+(j-1)*Dim.cx)*4+2] + MT->ucBits[(i+1+(j-1)*Dim.cx)*4+2] 
109               -MT->ucBits[(i-1+(j+1)*Dim.cx)*4+2] - MT->ucBits[(i+(j+1)*Dim.cx)*4+2] - MT->ucBits[(i+1+(j+1)*Dim.cx)*4+2]; 
110            Gy=  MT->ucBits[(i-1+(j-1)*Dim.cx)*4+2] + MT->ucBits[(i-1+j*Dim.cx)*4+2] + MT->ucBits[(i-1+(j+1)*Dim.cx)*4+2] 
111               -MT->ucBits[(i+1+(j+1)*Dim.cx)*4+2] - MT->ucBits[(i+1+j*Dim.cx)*4+2] - MT->ucBits[(i+1+(j+1)*Dim.cx)*4+2]; 
112            MT->ImgDest->ucBits[Pos]=(int)Limit(sqrt(Gx*Gx+Gy*Gy)); 
113            MT->ImgDest->ucBits[Pos+1]=MT->ImgDest->ucBits[Pos]; 
114            MT->ImgDest->ucBits[Pos+2]=MT->ImgDest->ucBits[Pos]; 
115            break; 
116   
117   
118          case GREEN: 
119            Gx=  MT->ucBits[(i-1+(j-1)*Dim.cx)*4+1] + MT->ucBits[(i+(j-1)*Dim.cx)*4+1] + MT->ucBits[(i+1+(j-1)*Dim.cx)*4+1] 
120               -MT->ucBits[(i-1+(j+1)*Dim.cx)*4+1] - MT->ucBits[(i+(j+1)*Dim.cx)*4+1] - MT->ucBits[(i+1+(j+1)*Dim.cx)*4+1]; 
121            Gy=  MT->ucBits[(i-1+(j-1)*Dim.cx)*4+1] + MT->ucBits[(i-1+j*Dim.cx)*4+1] + MT->ucBits[(i-1+(j+1)*Dim.cx)*4+1] 
122               -MT->ucBits[(i+1+(j+1)*Dim.cx)*4+1] - MT->ucBits[(i+1+j*Dim.cx)*4+1] - MT->ucBits[(i+1+(j+1)*Dim.cx)*4+1]; 
123            MT->ImgDest->ucBits[Pos]=(int)Limit(sqrt(Gx*Gx+Gy*Gy)); 
124            MT->ImgDest->ucBits[Pos+1]=MT->ImgDest->ucBits[Pos]; 
125            MT->ImgDest->ucBits[Pos+2]=MT->ImgDest->ucBits[Pos]; 
126            break; 
127   
128          case BLUE : 
129            Gx=  MT->ucBits[(i-1+(j-1)*Dim.cx)*4] + MT->ucBits[(i+(j-1)*Dim.cx)*4] + MT->ucBits[(i+1+(j-1)*Dim.cx)*4] 
130               -MT->ucBits[(i-1+(j+1)*Dim.cx)*4] - MT->ucBits[(i+(j+1)*Dim.cx)*4] - MT->ucBits[(i+1+(j+1)*Dim.cx)*4]; 
131            Gy=  MT->ucBits[(i-1+(j-1)*Dim.cx)*4] + MT->ucBits[(i-1+j*Dim.cx)*4] + MT->ucBits[(i-1+(j+1)*Dim.cx)*4] 
132               -MT->ucBits[(i+1+(j+1)*Dim.cx)*4] - MT->ucBits[(i+1+j*Dim.cx)*4] - MT->ucBits[(i+1+(j+1)*Dim.cx)*4]; 
133            MT->ImgDest->ucBits[Pos]=(int)Limit(sqrt(Gx*Gx+Gy*Gy)); 
134            MT->ImgDest->ucBits[Pos+1]=MT->ImgDest->ucBits[Pos]; 
135            MT->ImgDest->ucBits[Pos+2]=MT->ImgDest->ucBits[Pos]; 
136            break; 
137          } 
138      } 
139   
140   
141    return 1; 
142  } 
143   
144  bool CImage::Prewitt(int Type,CImage *ImgDest) 
145  { 
146    if(hBmp==0){ 
147      MessageBox(NULL,"Prewitt : L'image source est vide", 
148            NULL,MB_OK|MB_ICONWARNING); 
149      return 0; 
150    } 
151    if(ImgDest==0) 
152      ImgDest=this; 
153   
154    CImage ImgTmp; 
155    int i; 
156   
157      HANDLE  hThread[NB_THREAD]; 
158    MULTITHREAD MT[NB_THREAD]; 
159   
160    ImgTmp.CopyProp(this); 
161   
162    InitThread(MT,Width,Height); 
163   
164   
165    for(i=0;i<NB_THREAD;i++){ 
166      MT[i].Param1=Type; 
167      MT[i].ImgDest=&ImgTmp; 
168      MT[i].ucBits=ucBits; 
169    } 
170   
171    GetBitmapBits (hBmp,(Width*Height)*4,ucBits); 
172   
173    for(i=0;i<NB_THREAD;i++) 
174    { 
175      hThread[i]=CreateThread(NULL,0,PREWITT,&MT[i],0,0); 
176      if (hThread[i] == NULL) 
177      { 
178        MessageBox(NULL,"Prewitt : Erreur lors de la creation des threads", 
179            NULL,MB_OK|MB_ICONWARNING); 
180        return 0; 
181      } 
182    } 
183   
184    WaitForMultipleObjects(NB_THREAD, hThread, TRUE, INFINITE); 
185   
186    //Verifie si il y a eu des erreurs dans les threads 
187    for(i=0;i<NB_THREAD;i++){ 
188      CloseHandle(hThread[i]); 
189      if(MT[i].Error==1){ 
190        MessageBox(NULL,"Prewitt : Erreur lors de l'execution des threads", 
191            NULL,MB_OK|MB_ICONWARNING); 
192        return 0; 
193   
194      } 
195    } 
196   
197   
198   
199    ImgDest->Copy(&ImgTmp); 
200   
201    SetBitmapBits (ImgDest->hBmp,(Width*Height)*4,ImgDest->ucBits); 
202    return 1; 
203  } 
204   
205  /* 
206  bool CImage::Prewitt(int Type,CImage *ImgDest) 
207  { 
208    if(hBmp==0){ 
209      MessageBox(NULL,"Prewitt : L'image source est vide", 
210            NULL,MB_OK|MB_ICONWARNING); 
211      return 0; 
212    } 
213     
214    if(ImgDest!=0 && ImgDest!=this) 
215      ImgDest->Copy(this); 
216     
217    if(ImgDest==0) 
218      ImgDest=this; 
219     
220    int i,j; 
221    double *dX=new double[Width*Height],Grad; 
222    double *dY=new double[Width*Height]; 
223     
224    double *dX_Red,*dY_Red,*dX_Green,*dY_Green; 
225    if(Type==RGBi) 
226    { 
227      dX_Red=new double[Width*Height]; 
228      dY_Red=new double[Width*Height]; 
229   
230      dX_Green=new double[Width*Height]; 
231      dY_Green=new double[Width*Height]; 
232    } 
233   
234    //recupération des pixels 
235    GetBitmapBits(hBmp,Width*Height*4,ucBits); 
236     
237    for(i=1;i<Width-1;i++) 
238      for(j=1;j<Height-1;j++) 
239      { 
240        switch(Type) 
241        { 
242        case RGBi: 
243          dX_Red[(i+j*Width)]=GetPixel(i-1,j-1,RED)-GetPixel(i+1,j-1,RED) 
244             +GetPixel(i-1,j,RED)-GetPixel(i+1,j,RED) 
245             +GetPixel(i-1,j+1,RED)-GetPixel(i+1,j+1,RED);   
246          dY_Red[(i+j*Width)]=GetPixel(i-1,j-1,RED)+GetPixel(i,j-1,RED)+GetPixel(i+1,j-1,RED) 
247             -GetPixel(i-1,j+1,RED)-GetPixel(i,j+1,RED)-GetPixel(i+1,j+1,RED); 
248           
249          dX_Green[(i+j*Width)]=GetPixel(i-1,j-1,GREEN)-GetPixel(i+1,j-1,GREEN) 
250             +GetPixel(i-1,j,GREEN)-GetPixel(i+1,j,GREEN) 
251             +GetPixel(i-1,j+1,GREEN)-GetPixel(i+1,j+1,GREEN);   
252          dY_Green[(i+j*Width)]=GetPixel(i-1,j-1,GREEN)+GetPixel(i,j-1,GREEN)+GetPixel(i+1,j-1,GREEN) 
253             -GetPixel(i-1,j+1,GREEN)-GetPixel(i,j+1,GREEN)-GetPixel(i+1,j+1,GREEN); 
254           
255          dX[(i+j*Width)]=GetPixel(i-1,j-1,BLUE)-GetPixel(i+1,j-1,BLUE) 
256             +GetPixel(i-1,j,BLUE)-GetPixel(i+1,j,BLUE) 
257             +GetPixel(i-1,j+1,BLUE)-GetPixel(i+1,j+1,BLUE);   
258          dY[(i+j*Width)]=GetPixel(i-1,j-1,BLUE)+GetPixel(i,j-1,BLUE)+GetPixel(i+1,j-1,BLUE) 
259             -GetPixel(i-1,j+1,BLUE)-GetPixel(i,j+1,BLUE)-GetPixel(i+1,j+1,BLUE); 
260        break; 
261        default: 
262          dX[(i+j*Width)]=GetPixel(i-1,j-1,Type)-GetPixel(i+1,j-1,Type) 
263             +GetPixel(i-1,j,Type)-GetPixel(i+1,j,Type) 
264             +GetPixel(i-1,j+1,Type)-GetPixel(i+1,j+1,Type); 
265             
266          dY[(i+j*Width)]=GetPixel(i-1,j-1,Type)+GetPixel(i,j-1,Type)+GetPixel(i+1,j-1,Type) 
267             -GetPixel(i-1,j+1,Type)-GetPixel(i,j+1,Type)-GetPixel(i+1,j+1,Type); 
268          break; 
269        } 
270      } 
271   
272    switch(Type) 
273    { 
274    case RGBi: 
275      ImgDest->ImgType=RGBi; 
276      for(i=0,j=0;i<Width*Height*4;i+=4,j++) 
277      {   
278        Grad=sqrt(dX[j]*dX[j]+dY[j]*dY[j]); 
279        ImgDest->ucBits[i]=Limit((int)Grad); 
280        Grad=sqrt(dX_Green[j]*dX_Green[j]+dY_Green[j]*dY_Green[j]); 
281        ImgDest->ucBits[i+1]=Limit((int)Grad); 
282        Grad=sqrt(dX_Red[j]*dX_Red[j]+dY_Red[j]*dY_Red[j]); 
283        ImgDest->ucBits[i+2]=Limit((int)Grad); 
284      } 
285      delete []dX_Red; 
286      delete []dY_Red; 
287      delete []dX_Green; 
288      delete []dY_Green; 
289   
290      break; 
291     
292    default: 
293      ImgDest->ImgType=GRAY; 
294      for(i=0,j=0;i<Width*Height*4;i+=4,j++) 
295      { 
296        Grad=sqrt(dX[j]*dX[j]+dY[j]*dY[j]); 
297        ImgDest->ucBits[i]=Limit((int)Grad); 
298        ImgDest->ucBits[i+1]=Limit((int)Grad); 
299        ImgDest->ucBits[i+2]=Limit((int)Grad); 
300         
301      } 
302      break; 
303   
304   
305    } 
306    delete []dX; 
307    delete []dY; 
308     
309     
310    SetBitmapBits (ImgDest->hBmp,(Width*Height)*4,ImgDest->ucBits); 
311     
312    return 1; 
313  } 
314   
315   
316  */ 

lien1 lien2 lien3