Distance.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   
25  //***************************************************************************** 
26  //morCreateCircularStruct 
27  //Cette fonction permet de créer un élément structurant qui ressemble le plus  
28  //possible à un cercle. Plus le rayon sera grand, plus l'approximation du cercle sera 
29  //bonne. On ne crera que des éléments structurants de dimension impaire pour que le pixel 
30  //ou est appliqué l'opération soit au centre de l'élément structurant. Si le rayon est  
31  //paire, on augmentera sa taille de 1  
32  //****************************************************************************** 
33  bool *morCreateCircularStruct(int Rayon) 
34  { 
35    bool *Struct; 
36    int i,X,Y; 
37   
38    if(Rayon%2==0)      //Si l'élément est pair     
39      Rayon++;        //on le transforme en élément impaire 
40   
41   
42   
43    if(Rayon==1)        //la croix unité si Rayon = 1 
44    { 
45      Rayon=3; 
46      Struct=new bool[Rayon*Rayon]; 
47      Struct[0]=0; 
48      Struct[2]=0; 
49      Struct[6]=0; 
50      Struct[8]=0; 
51      Struct[1]=1; 
52      Struct[3]=1; 
53      Struct[4]=1; 
54      Struct[5]=1; 
55      Struct[7]=1; 
56   
57    } 
58    else 
59    { 
60      Struct=new bool[Rayon*Rayon]; 
61      for(i=0;i<Rayon*Rayon;i++) 
62      { 
63        X=i/Rayon; 
64        Y=i-X*Rayon; 
65   
66        X=X-((Rayon-1)/2); 
67        Y=Y-((Rayon-1)/2); 
68   
69        if(pow((double)X,2)*pow((double)Y,2)<=pow((double)Rayon/2+0.5,2)) 
70          Struct[i]=1; 
71        else 
72          Struct[i]=0; 
73   
74      } 
75    } 
76   
77    return Struct; 
78  } 
79   
80   
81  //OK 
82  bool CImage::morReconstruction(CImage *Marqueur,int Taille,CImage *ImgDest) 
83  { 
84    if(hBmp==0){ 
85      MessageBox(NULL,"morReconstruction: L'image source est vide", 
86            NULL,MB_OK|MB_ICONWARNING); 
87      return 0; 
88    } 
89    if(Marqueur->hBmp==0){ 
90      MessageBox(NULL,"morReconstruction: L'image des marqueurs est vide", 
91            NULL,MB_OK|MB_ICONWARNING); 
92      return 0; 
93    } 
94   
95    if(ImgType!=BIN){ 
96      MessageBox(NULL,"morReconstruction : L'image source doit etre binaire", 
97            NULL,MB_OK|MB_ICONWARNING); 
98      return 0; 
99    } 
100    if(Marqueur->ImgType!=BIN){ 
101      MessageBox(NULL,"morReconstruction : L'image des marqueurs doit etre binaire", 
102            NULL,MB_OK|MB_ICONWARNING); 
103      return 0; 
104    } 
105   
106    if(ImgDest!=0 && ImgDest!=this) 
107      ImgDest->Copy(this); 
108    if(ImgDest==0) 
109      ImgDest=this; 
110    //Aire des 2 images 
111    int A1,A2; 
112    bool *Struct; 
113    CImage ImgTmp; 
114    Struct=morCreateCircularStruct(Taille); 
115    ImgTmp.Copy(Marqueur); 
116    //création de l'image des marqueurs 
117    ImgTmp.AND(this); 
118   
119    A1=ImgTmp.NbPixel(255,255,255); 
120    A2=0; 
121   
122    while(A1!=A2)        //on dilate le marqueur jusqu'à convergence 
123    { 
124      A2=A1; 
125   
126      ImgTmp.Dilatation(Struct,Taille*Taille,TRUE); 
127      ImgTmp.AND(this); 
128      A1=ImgTmp.NbPixel(255,255,255); 
129   
130    } 
131    delete []Struct; 
132    ImgDest->Copy(&ImgTmp); 
133    ImgTmp.Nettoyage(); 
134    return true; 
135   
136  } 
137   
138   
139  //OK 
140  bool CImage::morCloseHole(int Taille,CImage *ImgDest) 
141  { 
142    if(hBmp==0){ 
143      MessageBox(NULL,"DistanceMorphologique: L'image source est vide", 
144            NULL,MB_OK|MB_ICONWARNING); 
145      return 0; 
146    } 
147   
148    if(ImgType!=BIN){ 
149      MessageBox(NULL,"DistanceMorphologique : L'image source doit etre binaire", 
150            NULL,MB_OK|MB_ICONWARNING); 
151      return 0; 
152    } 
153    if(ImgDest!=0 && ImgDest!=this) 
154      ImgDest->CopyProp(this); 
155    if(ImgDest==0) 
156      ImgDest=this; 
157   
158    CImage ImgMarqueur,ImgTmp; 
159    ImgMarqueur.CopyProp(this); 
160    ImgMarqueur.Fill(0,0,0); 
161    ImgMarqueur.DrawHorizontalLine(0,255,255,255); 
162    ImgMarqueur.DrawHorizontalLine(Height-1,255,255,255); 
163    ImgMarqueur.DrawVerticalLine(0,255,255,255); 
164    ImgMarqueur.DrawVerticalLine(Width-1,255,255,255); 
165   
166    this->NOT(&ImgTmp); 
167   
168    ImgTmp.morReconstruction(&ImgMarqueur,Taille); 
169   
170    ImgTmp.NOT(ImgDest); 
171    ImgTmp.Nettoyage(); 
172    ImgMarqueur.Nettoyage(); 
173   
174    return 1; 
175  } 
176   
177   
178  bool CImage::DistanceMorphologique(int Taille,bool Bordure,CImage *ImgDest) 
179  { 
180    if(hBmp==0){ 
181      MessageBox(NULL,"DistanceMorphologique: L'image source est vide", 
182            NULL,MB_OK|MB_ICONWARNING); 
183      return 0; 
184    } 
185   
186    if(ImgType!=BIN){ 
187      MessageBox(NULL,"DistanceMorphologique : L'image source doit etre binaire", 
188            NULL,MB_OK|MB_ICONWARNING); 
189      return 0; 
190    } 
191   
192    if(ImgDest!=0 && ImgDest!=this) 
193      ImgDest->Copy(this); 
194    if(ImgDest==0) 
195      ImgDest=this; 
196   
197    int Cpt,Num,i; 
198    bool *Struct; 
199    CImage ImgTmp,ImgTmpDest; 
200   
201    Cpt=Width*Height; 
202    Num=0; 
203   
204    ImgTmp.Copy(this); 
205    ImgTmpDest.CopyProp(this); 
206    ImgTmpDest.Fill(255,255,255); 
207   
208    Struct=morCreateCircularStruct(Taille); 
209   
210    if(Bordure) 
211    { 
212      for(i=0;i<Width*4;i+=4) 
213      { 
214        ImgTmp.ucBits[i]=255; 
215        ImgTmp.ucBits[4*Width*(Height-1)+i]=255; 
216      } 
217      for(i=0;i<Height;i++) 
218      { 
219        ImgTmp.ucBits[i*4*Width]=255; 
220        ImgTmp.ucBits[i*4*Width+4*Width-4]=255; 
221      } 
222    } 
223    int NbIter=0; 
224    do 
225    { 
226      for(i=0;i<Height*Width*4;i+=4) 
227        if(ImgTmp.ucBits[i]==255 && ImgTmpDest.ucBits[i]==255){ 
228          ImgTmpDest.ucBits[i]=Num; 
229          ImgTmpDest.ucBits[i+1]=Num; 
230          ImgTmpDest.ucBits[i+2]=Num; 
231          Cpt--; 
232        } 
233   
234      ImgTmp.Dilatation(Struct,Taille*Taille,0); 
235      Num++; 
236      NbIter++; 
237   
238    } 
239    while(Cpt>0 && NbIter<200); 
240   
241   
242    ImgDest->Copy(&ImgTmpDest); 
243    ImgDest->ImgType=GRAY; 
244    SetBitmapBits (ImgDest->hBmp,(Width*Height)*4,ImgDest->ucBits); 
245    delete []Struct; 
246    ImgTmpDest.Nettoyage(); 
247    ImgTmp.Nettoyage(); 
248    return true; 
249  } 

lien1 lien2 lien3