root / src / lsm_lib.h @ 19
Historique | Voir | Annoter | Télécharger (16,48 ko)
1 | 18 | akiss | #include <iostream> |
---|---|---|---|
2 | 18 | akiss | #include <math.h> |
3 | 18 | akiss | #include <sstream> |
4 | 18 | akiss | #include <vector> |
5 | 18 | akiss | #include <fstream> |
6 | 18 | akiss | #include <algorithm> |
7 | 18 | akiss | |
8 | 18 | akiss | #include "CImg.h" |
9 | 18 | akiss | |
10 | 18 | akiss | using namespace cimg_library; |
11 | 18 | akiss | using namespace std; |
12 | 18 | akiss | |
13 | 18 | akiss | |
14 | 18 | akiss | //**************************************** GLOBAL IMAGE *************************************************************************
|
15 | 18 | akiss | |
16 | 18 | akiss | //Add black slices on each side of the image
|
17 | 18 | akiss | //----------------------------------------------------------------------------
|
18 | 18 | akiss | CImg<float> add_side_slices(CImg<float> const & img, int side) |
19 | 18 | akiss | { |
20 | 18 | akiss | int s=side*2; |
21 | 18 | akiss | CImg<float> newImg(img._width+s,img._height+s,img._depth+s,1,1); |
22 | 18 | akiss | |
23 | 18 | akiss | cimg_forXYZ(img,x,y,z) |
24 | 18 | akiss | { |
25 | 18 | akiss | newImg(x+side,y+side,z+side)=img(x,y,z); |
26 | 18 | akiss | } |
27 | 18 | akiss | return newImg;
|
28 | 18 | akiss | } |
29 | 18 | akiss | |
30 | 18 | akiss | //Remove slices
|
31 | 18 | akiss | //----------------------------------------------------------------------------
|
32 | 18 | akiss | CImg<float> remove_side_slices(CImg<float> const & img, int side) |
33 | 18 | akiss | { |
34 | 18 | akiss | int s=side*2; |
35 | 18 | akiss | CImg<float> newImg(img._width-s,img._height-s,img._depth-s,1,0); |
36 | 18 | akiss | |
37 | 18 | akiss | cimg_forXYZ(newImg,x,y,z) |
38 | 18 | akiss | { |
39 | 18 | akiss | newImg(x,y,z)=img(x+side,y+side,z+side); |
40 | 18 | akiss | } |
41 | 18 | akiss | return newImg;
|
42 | 18 | akiss | } |
43 | 18 | akiss | |
44 | 18 | akiss | //Threshold linear along Z 1:background 0:cells
|
45 | 18 | akiss | //----------------------------------------------------------------------------
|
46 | 18 | akiss | CImg<unsigned char> threshold_linear_alongZ(CImg<float> const & img, int t1, int t2) |
47 | 18 | akiss | { |
48 | 18 | akiss | CImg<unsigned char> outside(img._width,img._height,img._depth,1,0); |
49 | 18 | akiss | for(int z=0; z<img._depth ; z++) |
50 | 18 | akiss | { |
51 | 18 | akiss | cimg_forXY(outside,x,y) |
52 | 18 | akiss | { |
53 | 18 | akiss | float thresh = t1 + (t2-t1)*(z*1.0/img._depth); |
54 | 18 | akiss | if(img(x,y,z)<thresh)
|
55 | 18 | akiss | {outside(x,y,z)=1;}
|
56 | 18 | akiss | } |
57 | 18 | akiss | } |
58 | 18 | akiss | outside.label(); |
59 | 18 | akiss | cimg_forXYZ(outside,x,y,z) |
60 | 18 | akiss | { |
61 | 18 | akiss | if(outside(x,y,z)>0) {outside(x,y,z)=0;} |
62 | 18 | akiss | else {outside(x,y,z)=1;} |
63 | 18 | akiss | } |
64 | 18 | akiss | return outside;
|
65 | 18 | akiss | } |
66 | 18 | akiss | |
67 | 18 | akiss | //LSM contour init +c0 background, -c0 cells
|
68 | 18 | akiss | //--------------------------------------------------------------------------
|
69 | 18 | akiss | CImg<float> lsm_contour_init(CImg<unsigned char> const & region,int c0) |
70 | 18 | akiss | { |
71 | 18 | akiss | CImg<float> initLSM(region._width,region._height,region._depth,1,c0); |
72 | 18 | akiss | initLSM=initLSM-2*c0*region;
|
73 | 18 | akiss | return initLSM;
|
74 | 18 | akiss | } |
75 | 18 | akiss | |
76 | 18 | akiss | //Gradient 3D with central finite differences
|
77 | 18 | akiss | //----------------------------------------------------------------------------
|
78 | 18 | akiss | CImgList<float> gradient(CImg<float> const & img) |
79 | 18 | akiss | { |
80 | 18 | akiss | //List of 3 images the same size as img
|
81 | 18 | akiss | CImgList<float> grad(3,img._width,img._height,img._depth,1,0); |
82 | 18 | akiss | |
83 | 18 | akiss | //Image loop with a 3*3*3 neighborhood
|
84 | 18 | akiss | CImg_3x3x3(I,float);
|
85 | 18 | akiss | cimg_for3x3x3(img,x,y,z,0,I,float) |
86 | 18 | akiss | { |
87 | 18 | akiss | grad(0,x,y,z) = (Incc - Ipcc)/2; //grad x = (img(x+1,y,z)-img(x-1,y,z))/2 |
88 | 18 | akiss | grad(1,x,y,z) = (Icnc - Icpc)/2; //grad y |
89 | 18 | akiss | grad(2,x,y,z) = (Iccn - Iccp)/2; //grad z |
90 | 18 | akiss | } |
91 | 18 | akiss | return grad;
|
92 | 18 | akiss | } |
93 | 18 | akiss | |
94 | 18 | akiss | //Norm of the gradient
|
95 | 18 | akiss | //---------------------------------------------------------------------------
|
96 | 18 | akiss | CImg<float> gradient_norm(CImg<float> const & img) |
97 | 18 | akiss | { |
98 | 18 | akiss | CImgList<float> grad = gradient(img);
|
99 | 18 | akiss | CImg<float> res(grad[0]._width,grad[0]._height,grad[0]._depth,1,0); |
100 | 18 | akiss | float f=0; |
101 | 18 | akiss | cimg_forXYZ(res,x,y,z) |
102 | 18 | akiss | { |
103 | 18 | akiss | f=grad(0,x,y,z)*grad(0,x,y,z) + grad(1,x,y,z)*grad(1,x,y,z) + grad(2,x,y,z)*grad(2,x,y,z); |
104 | 18 | akiss | res(x,y,z)=sqrt(f); |
105 | 18 | akiss | } |
106 | 18 | akiss | return res;
|
107 | 18 | akiss | } |
108 | 18 | akiss | |
109 | 18 | akiss | |
110 | 18 | akiss | //Edge indicator
|
111 | 18 | akiss | //---------------------------------------------------------------------------
|
112 | 18 | akiss | CImg<float> edge_indicator(CImgList<float> const & grad) |
113 | 18 | akiss | { |
114 | 18 | akiss | CImg<float> res(grad[0]._width,grad[0]._height,grad[0]._depth,1,0); |
115 | 18 | akiss | float f=0; |
116 | 18 | akiss | cimg_forXYZ(res,x,y,z) |
117 | 18 | akiss | { |
118 | 18 | akiss | f=grad(0,x,y,z)*grad(0,x,y,z) + grad(1,x,y,z)*grad(1,x,y,z) + grad(2,x,y,z)*grad(2,x,y,z); |
119 | 18 | akiss | res(x,y,z)=1.0/(1.0+f); |
120 | 18 | akiss | //res(x,y,z)=exp(-f);
|
121 | 18 | akiss | } |
122 | 18 | akiss | return res;
|
123 | 18 | akiss | } |
124 | 18 | akiss | |
125 | 18 | akiss | //Edge indicator 1 (gradient)
|
126 | 18 | akiss | //---------------------------------------------------------------------------
|
127 | 18 | akiss | CImg<float> edge_indicator1(CImg<float> const & img) |
128 | 18 | akiss | { |
129 | 18 | akiss | CImgList<float> grad;
|
130 | 18 | akiss | grad = gradient(img); |
131 | 18 | akiss | CImg<float> res(img._width,img._height,img._depth,1,0); |
132 | 18 | akiss | float f=0; |
133 | 18 | akiss | cimg_forXYZ(res,x,y,z) |
134 | 18 | akiss | { |
135 | 18 | akiss | f=grad(0,x,y,z)*grad(0,x,y,z) + grad(1,x,y,z)*grad(1,x,y,z) + grad(2,x,y,z)*grad(2,x,y,z); |
136 | 18 | akiss | res(x,y,z)=1.0/(1.0+f); |
137 | 18 | akiss | } |
138 | 18 | akiss | return res;
|
139 | 18 | akiss | } |
140 | 18 | akiss | |
141 | 18 | akiss | CImg<float> edge_indicator1(CImg<float> const & img, float gamma) |
142 | 18 | akiss | { |
143 | 18 | akiss | CImgList<float> grad;
|
144 | 18 | akiss | grad = gradient(img); |
145 | 18 | akiss | CImg<float> res(img._width,img._height,img._depth,1,0); |
146 | 18 | akiss | float f=0; |
147 | 18 | akiss | cimg_forXYZ(res,x,y,z) |
148 | 18 | akiss | { |
149 | 18 | akiss | f=grad(0,x,y,z)*grad(0,x,y,z) + grad(1,x,y,z)*grad(1,x,y,z) + grad(2,x,y,z)*grad(2,x,y,z); |
150 | 18 | akiss | res(x,y,z)=1.0/(1.0+f/gamma/gamma); |
151 | 18 | akiss | } |
152 | 18 | akiss | return res;
|
153 | 18 | akiss | } |
154 | 18 | akiss | |
155 | 18 | akiss | //Edge indicator 2 (hessienne, computed without smoothing)
|
156 | 18 | akiss | //---------------------------------------------------------------------------
|
157 | 18 | akiss | CImg<float> edge_indicator2(CImg<float> const & img) |
158 | 18 | akiss | { |
159 | 18 | akiss | CImg<float> res(img._width,img._height,img._depth,1,0); |
160 | 18 | akiss | float f=0; |
161 | 18 | akiss | cimg_forXYZ(res,x,y,z) |
162 | 18 | akiss | { |
163 | 18 | akiss | int xp=x-1; |
164 | 18 | akiss | if (x==0){xp=x;} |
165 | 18 | akiss | int xn=x+1; |
166 | 18 | akiss | if (x==img._width-1){xn=x;} |
167 | 18 | akiss | int yp=y-1; |
168 | 18 | akiss | if (y==0){yp=y;} |
169 | 18 | akiss | int yn=y+1; |
170 | 18 | akiss | if (y==img._height-1){yn=y;} |
171 | 18 | akiss | int zp=z-1; |
172 | 18 | akiss | if (z==0){zp=z;} |
173 | 18 | akiss | int zn=z+1; |
174 | 18 | akiss | if (z==img._depth-1){zn=z;} |
175 | 18 | akiss | |
176 | 18 | akiss | CImg<float> hess(3,3,1,1,0); |
177 | 18 | akiss | hess(0,0) = img(xp,y,z) + img(xn,y,z) - 2*img(x,y,z); // Hxx |
178 | 18 | akiss | hess(1,1) = img(x,yp,z) + img(x,yn,z) - 2*img(x,y,z); // Hyy |
179 | 18 | akiss | hess(2,2) = img(x,y,zp) + img(x,y,zn) - 2*img(x,y,z); // Hzz |
180 | 18 | akiss | hess(1,0) = hess(0,1) = (img(xp,yp,z) + img(xn,yn,z) - img(xp,yn,z) - img(xn,yp,z))/4; // Hxy = Hyx |
181 | 18 | akiss | hess(2,0) = hess(0,2) = (img(xp,y,zp) + img(xn,y,zn) - img(xp,y,zn) - img(xn,y,zp))/4; // Hxz = Hzx |
182 | 18 | akiss | hess(2,1) = hess(1,2) = (img(x,yp,zp) + img(x,yn,zn) - img(x,yp,zn) - img(x,yn,zp))/4; // Hyz = Hzy |
183 | 18 | akiss | |
184 | 18 | akiss | //val : 3 eigen values as an array, decreasing order
|
185 | 18 | akiss | //vec : 3 eigen vectors as a 3*3 image
|
186 | 18 | akiss | //have to be double or create NaN
|
187 | 18 | akiss | CImg<double> val,vec;
|
188 | 18 | akiss | hess.symmetric_eigen(val,vec); |
189 | 18 | akiss | if (val[2]>0) val[2]=0; |
190 | 18 | akiss | val[2]=-val[2]; |
191 | 18 | akiss | //res(x,y,z)=1.0/(1.0 +val[2]*(50/3.)); //h=g test4
|
192 | 18 | akiss | //res(x,y,z)=1.0/(1.0 +val[2]*val[2]*(50/3.)*(50/3.) );
|
193 | 18 | akiss | //res(x,y,z)=1.0/(1.0 +exp(-val[2]));
|
194 | 18 | akiss | //res(x,y,z)=exp(-val[2]);
|
195 | 18 | akiss | //res(x,y,z)=exp(-val[2]*val[2]);
|
196 | 18 | akiss | res(x,y,z)=1.0/(1.0 +val[2]*val[2]); |
197 | 18 | akiss | } |
198 | 18 | akiss | return res;
|
199 | 18 | akiss | } |
200 | 18 | akiss | |
201 | 18 | akiss | //Edge indicator 2 (hessienne, computed with smoothing)
|
202 | 18 | akiss | //---------------------------------------------------------------------------
|
203 | 18 | akiss | CImg<float> edge_indicator2s(CImg<float> const & img, float gamma) |
204 | 18 | akiss | { |
205 | 18 | akiss | CImg<float> res(img._width,img._height,img._depth,1,0); |
206 | 18 | akiss | |
207 | 18 | akiss | // make a minimal blur before taking derivatives
|
208 | 18 | akiss | CImg<float> imgBlur=img.get_blur(2); |
209 | 18 | akiss | |
210 | 18 | akiss | float f=0; |
211 | 18 | akiss | cimg_forXYZ(res,x,y,z) |
212 | 18 | akiss | { |
213 | 18 | akiss | int xp=x-1; |
214 | 18 | akiss | if (x==0){xp=x;} |
215 | 18 | akiss | int xn=x+1; |
216 | 18 | akiss | if (x==img._width-1){xn=x;} |
217 | 18 | akiss | int yp=y-1; |
218 | 18 | akiss | if (y==0){yp=y;} |
219 | 18 | akiss | int yn=y+1; |
220 | 18 | akiss | if (y==img._height-1){yn=y;} |
221 | 18 | akiss | int zp=z-1; |
222 | 18 | akiss | if (z==0){zp=z;} |
223 | 18 | akiss | int zn=z+1; |
224 | 18 | akiss | if (z==img._depth-1){zn=z;} |
225 | 18 | akiss | |
226 | 18 | akiss | CImg<float> hess(3,3,1,1,0); |
227 | 18 | akiss | hess(0,0) = imgBlur(xp,y,z) + imgBlur(xn,y,z) - 2*imgBlur(x,y,z); // Hxx |
228 | 18 | akiss | hess(1,1) = imgBlur(x,yp,z) + imgBlur(x,yn,z) - 2*imgBlur(x,y,z); // Hyy |
229 | 18 | akiss | hess(2,2) = imgBlur(x,y,zp) + imgBlur(x,y,zn) - 2*imgBlur(x,y,z); // Hzz |
230 | 18 | akiss | hess(1,0) = hess(0,1) = (imgBlur(xp,yp,z) + imgBlur(xn,yn,z) - imgBlur(xp,yn,z) - imgBlur(xn,yp,z))/4; // Hxy = Hyx |
231 | 18 | akiss | hess(2,0) = hess(0,2) = (imgBlur(xp,y,zp) + imgBlur(xn,y,zn) - imgBlur(xp,y,zn) - imgBlur(xn,y,zp))/4; // Hxz = Hzx |
232 | 18 | akiss | hess(2,1) = hess(1,2) = (imgBlur(x,yp,zp) + imgBlur(x,yn,zn) - imgBlur(x,yp,zn) - imgBlur(x,yn,zp))/4; // Hyz = Hzy |
233 | 18 | akiss | |
234 | 18 | akiss | //val : 3 eigen values as an array, decreasing order
|
235 | 18 | akiss | //vec : 3 eigen vectors as a 3*3 image
|
236 | 18 | akiss | //have to be double or create NaN
|
237 | 18 | akiss | CImg<double> val,vec;
|
238 | 18 | akiss | hess.symmetric_eigen(val,vec); |
239 | 18 | akiss | if (val[2]>0) val[2]=0; |
240 | 18 | akiss | val[2]=-val[2]; |
241 | 18 | akiss | res(x,y,z)=1.0/(1.0 +val[2]*val[2]/gamma/gamma); |
242 | 18 | akiss | } |
243 | 18 | akiss | return res;
|
244 | 18 | akiss | } |
245 | 18 | akiss | |
246 | 18 | akiss | |
247 | 18 | akiss | CImg<float> edge_indicator2(CImg<float> const & img, float gamma) |
248 | 18 | akiss | { |
249 | 18 | akiss | CImg<float> res(img._width,img._height,img._depth,1,0); |
250 | 18 | akiss | float f=0; |
251 | 18 | akiss | cimg_forXYZ(res,x,y,z) |
252 | 18 | akiss | { |
253 | 18 | akiss | int xp=x-1; |
254 | 18 | akiss | if (x==0){xp=x;} |
255 | 18 | akiss | int xn=x+1; |
256 | 18 | akiss | if (x==img._width-1){xn=x;} |
257 | 18 | akiss | int yp=y-1; |
258 | 18 | akiss | if (y==0){yp=y;} |
259 | 18 | akiss | int yn=y+1; |
260 | 18 | akiss | if (y==img._height-1){yn=y;} |
261 | 18 | akiss | int zp=z-1; |
262 | 18 | akiss | if (z==0){zp=z;} |
263 | 18 | akiss | int zn=z+1; |
264 | 18 | akiss | if (z==img._depth-1){zn=z;} |
265 | 18 | akiss | |
266 | 18 | akiss | CImg<float> hess(3,3,1,1,0); |
267 | 18 | akiss | hess(0,0) = img(xp,y,z) + img(xn,y,z) - 2*img(x,y,z); // Hxx |
268 | 18 | akiss | hess(1,1) = img(x,yp,z) + img(x,yn,z) - 2*img(x,y,z); // Hyy |
269 | 18 | akiss | hess(2,2) = img(x,y,zp) + img(x,y,zn) - 2*img(x,y,z); // Hzz |
270 | 18 | akiss | hess(1,0) = hess(0,1) = (img(xp,yp,z) + img(xn,yn,z) - img(xp,yn,z) - img(xn,yp,z))/4; // Hxy = Hyx |
271 | 18 | akiss | hess(2,0) = hess(0,2) = (img(xp,y,zp) + img(xn,y,zn) - img(xp,y,zn) - img(xn,y,zp))/4; // Hxz = Hzx |
272 | 18 | akiss | hess(2,1) = hess(1,2) = (img(x,yp,zp) + img(x,yn,zn) - img(x,yp,zn) - img(x,yn,zp))/4; // Hyz = Hzy |
273 | 18 | akiss | |
274 | 18 | akiss | //val : 3 eigen values as an array, decreasing order
|
275 | 18 | akiss | //vec : 3 eigen vectors as a 3*3 image
|
276 | 18 | akiss | //have to be double or create NaN
|
277 | 18 | akiss | CImg<double> val,vec;
|
278 | 18 | akiss | hess.symmetric_eigen(val,vec); |
279 | 18 | akiss | if (val[2]>0) val[2]=0; |
280 | 18 | akiss | //val[2]=-val[2];
|
281 | 18 | akiss | res(x,y,z)=1.0/(1.0 +val[2]*val[2]/gamma/gamma); |
282 | 18 | akiss | } |
283 | 18 | akiss | return res;
|
284 | 18 | akiss | } |
285 | 18 | akiss | |
286 | 18 | akiss | //Edge indicator 3 (image based)
|
287 | 18 | akiss | //---------------------------------------------------------------------------
|
288 | 18 | akiss | CImg<float> edge_indicator3(CImg<float> const & img) |
289 | 18 | akiss | { |
290 | 18 | akiss | CImg<float> res(img._width,img._height,img._depth,1,0); |
291 | 18 | akiss | cimg_forXYZ(res,x,y,z) |
292 | 18 | akiss | { |
293 | 18 | akiss | res(x,y,z)=1.0/(1.0+img(x,y,z)*img(x,y,z)); |
294 | 18 | akiss | } |
295 | 18 | akiss | return res;
|
296 | 18 | akiss | } |
297 | 18 | akiss | |
298 | 18 | akiss | CImg<float> edge_indicator3(CImg<float> const & img, float gamma) |
299 | 18 | akiss | { |
300 | 18 | akiss | CImg<float> res(img._width,img._height,img._depth,1,0); |
301 | 18 | akiss | cimg_forXYZ(res,x,y,z) |
302 | 18 | akiss | { |
303 | 18 | akiss | res(x,y,z)=1.0/(1.0+(img(x,y,z)/gamma)*(img(x,y,z)/gamma)); |
304 | 18 | akiss | } |
305 | 18 | akiss | return res;
|
306 | 18 | akiss | } |
307 | 18 | akiss | |
308 | 18 | akiss | //Edge image (based on lambda3 of the hessien)
|
309 | 18 | akiss | //---------------------------------------------------------------------------
|
310 | 18 | akiss | CImg<float> edge_lambda3(CImg<float> const & img) |
311 | 18 | akiss | { |
312 | 18 | akiss | CImg<float> res(img._width,img._height,img._depth,1,0); |
313 | 18 | akiss | float f=0; |
314 | 18 | akiss | cimg_forXYZ(res,x,y,z) |
315 | 18 | akiss | { |
316 | 18 | akiss | int xp=x-1; |
317 | 18 | akiss | if (x==0){xp=x;} |
318 | 18 | akiss | int xn=x+1; |
319 | 18 | akiss | if (x==img._width-1){xn=x;} |
320 | 18 | akiss | int yp=y-1; |
321 | 18 | akiss | if (y==0){yp=y;} |
322 | 18 | akiss | int yn=y+1; |
323 | 18 | akiss | if (y==img._height-1){yn=y;} |
324 | 18 | akiss | int zp=z-1; |
325 | 18 | akiss | if (z==0){zp=z;} |
326 | 18 | akiss | int zn=z+1; |
327 | 18 | akiss | if (z==img._depth-1){zn=z;} |
328 | 18 | akiss | |
329 | 18 | akiss | CImg<float> hess(3,3,1,1,0); |
330 | 18 | akiss | hess(0,0) = img(xp,y,z) + img(xn,y,z) - 2*img(x,y,z); // Hxx |
331 | 18 | akiss | hess(1,1) = img(x,yp,z) + img(x,yn,z) - 2*img(x,y,z); // Hyy |
332 | 18 | akiss | hess(2,2) = img(x,y,zp) + img(x,y,zn) - 2*img(x,y,z); // Hzz |
333 | 18 | akiss | hess(1,0) = hess(0,1) = (img(xp,yp,z) + img(xn,yn,z) - img(xp,yn,z) - img(xn,yp,z))/4; // Hxy = Hyx |
334 | 18 | akiss | hess(2,0) = hess(0,2) = (img(xp,y,zp) + img(xn,y,zn) - img(xp,y,zn) - img(xn,y,zp))/4; // Hxz = Hzx |
335 | 18 | akiss | hess(2,1) = hess(1,2) = (img(x,yp,zp) + img(x,yn,zn) - img(x,yp,zn) - img(x,yn,zp))/4; // Hyz = Hzy |
336 | 18 | akiss | |
337 | 18 | akiss | //val : 3 eigen values as an array, decreasing order
|
338 | 18 | akiss | //vec : 3 eigen vectors as a 3*3 image
|
339 | 18 | akiss | //have to be double or create NaN
|
340 | 18 | akiss | CImg<double> val,vec;
|
341 | 18 | akiss | hess.symmetric_eigen(val,vec); |
342 | 18 | akiss | if (val[2]>0) val[2]=0; |
343 | 18 | akiss | res(x,y,z)=-val[2];
|
344 | 18 | akiss | } |
345 | 18 | akiss | return res;
|
346 | 18 | akiss | } |
347 | 18 | akiss | |
348 | 18 | akiss | |
349 | 18 | akiss | //Wall indicator
|
350 | 18 | akiss | //---------------------------------------------------------------------------
|
351 | 18 | akiss | CImg<float> wall_indicator(CImg<float> const & img) |
352 | 18 | akiss | { |
353 | 18 | akiss | CImg<float> res(img._width,img._height,img._depth,1,0); |
354 | 18 | akiss | cimg_forXYZ(res,x,y,z) |
355 | 18 | akiss | { |
356 | 18 | akiss | res(x,y,z)=1.0/(1.0+(img(x,y,z)*img(x,y,z))); |
357 | 18 | akiss | } |
358 | 18 | akiss | return res;
|
359 | 18 | akiss | } |
360 | 18 | akiss | |
361 | 18 | akiss | //Dirac function
|
362 | 18 | akiss | //-------------------------------------------------------------------------
|
363 | 18 | akiss | CImg<float> Dirac(CImg<float> const & img, float sigma) |
364 | 18 | akiss | { |
365 | 18 | akiss | CImg<float> fImg(img._width,img._height,img._depth,1,0); |
366 | 18 | akiss | float f=0; |
367 | 18 | akiss | cimg_forXYZ(img,x,y,z) |
368 | 18 | akiss | { |
369 | 18 | akiss | if(abs(img(x,y,z))<=sigma)
|
370 | 18 | akiss | { |
371 | 18 | akiss | f=(1.0/(2*sigma))*(1+cos(M_PI*img(x,y,z)/sigma)); |
372 | 18 | akiss | } |
373 | 18 | akiss | else {f=0;} |
374 | 18 | akiss | fImg(x,y,z)=f; |
375 | 18 | akiss | } |
376 | 18 | akiss | return fImg;
|
377 | 18 | akiss | } |
378 | 18 | akiss | |
379 | 18 | akiss | //Normal vector
|
380 | 18 | akiss | //------------------------------------------------------------------------
|
381 | 18 | akiss | CImgList<float> normal_vector(CImg<float> const & img) |
382 | 18 | akiss | { |
383 | 18 | akiss | CImgList<float> normal_vector(3,img._width,img._height,img._depth,1,0); |
384 | 18 | akiss | |
385 | 18 | akiss | CImg_3x3x3(I,float);
|
386 | 18 | akiss | cimg_for3x3x3(img,x,y,z,0,I,float) |
387 | 18 | akiss | { |
388 | 18 | akiss | float nx = (Incc-Ipcc)/2.0; |
389 | 18 | akiss | float ny = (Icnc-Icpc)/2.0; |
390 | 18 | akiss | float nz = (Iccn-Iccp)/2.0; |
391 | 18 | akiss | //border
|
392 | 18 | akiss | if((x==0)or(y==0)or(z==0)) |
393 | 18 | akiss | {nx=ny=nz=0;}
|
394 | 18 | akiss | if((x==img.width()-1)or(y==img.height()-1)or(z==img.depth()-1)) |
395 | 18 | akiss | {nx=ny=nz=0;}
|
396 | 18 | akiss | |
397 | 18 | akiss | float norm=1; |
398 | 18 | akiss | if((nx!=0)or(ny!=0)or(nz!=0)) |
399 | 18 | akiss | {norm = sqrt(nx*nx+ny*ny+nz*nz);} |
400 | 18 | akiss | |
401 | 18 | akiss | normal_vector(0,x,y,z)=nx/norm;
|
402 | 18 | akiss | normal_vector(1,x,y,z)=ny/norm;
|
403 | 18 | akiss | normal_vector(2,x,y,z)=nz/norm;
|
404 | 18 | akiss | } |
405 | 18 | akiss | return normal_vector;
|
406 | 18 | akiss | } |
407 | 18 | akiss | |
408 | 18 | akiss | |
409 | 18 | akiss | //Curvature
|
410 | 18 | akiss | //------------------------------------------------------------------------
|
411 | 18 | akiss | CImg<float> curvature2(CImgList<float> const & N) |
412 | 18 | akiss | { |
413 | 18 | akiss | CImg<float> K(N[0]._width,N[0]._height,N[0]._depth,1,0); |
414 | 18 | akiss | cimg_forXYZ(N[0],x,y,z)
|
415 | 18 | akiss | { |
416 | 18 | akiss | float kx=0; |
417 | 18 | akiss | float ky=0; |
418 | 18 | akiss | float kz=0; |
419 | 18 | akiss | if(x==0) |
420 | 18 | akiss | {kx=N[0](x+1,y,z)-N[0](x,y,z);} |
421 | 18 | akiss | else if(x==N[0]._width-1) |
422 | 18 | akiss | {kx=N[0](x,y,z)-N[0](x-1,y,z);} |
423 | 18 | akiss | else
|
424 | 18 | akiss | {kx=(N[0](x+1,y,z)-N[0](x-1,y,z))/2.0;} |
425 | 18 | akiss | |
426 | 18 | akiss | if(y==0) |
427 | 18 | akiss | {ky=N[1](x,y+1,z)-N[1](x,y,z);} |
428 | 18 | akiss | else if(y==N[1]._height-1) |
429 | 18 | akiss | {ky=N[1](x,y,z)-N[1](x,y-1,z);} |
430 | 18 | akiss | else
|
431 | 18 | akiss | {ky=(N[1](x,y+1,z)-N[1](x,y-1,z))/2.0;} |
432 | 18 | akiss | |
433 | 18 | akiss | if(z==0) |
434 | 18 | akiss | {kz=N[2](x,y,z+1)-N[2](x,y,z);} |
435 | 18 | akiss | else if(z==N[2]._depth-1) |
436 | 18 | akiss | {kz=N[2](x,y,z)-N[2](x,y,z-1);} |
437 | 18 | akiss | else
|
438 | 18 | akiss | {kz=(N[2](x,y,z+1)-N[2](x,y,z-1))/2.0;} |
439 | 18 | akiss | |
440 | 18 | akiss | K(x,y,z)=kx+ky+kz; |
441 | 18 | akiss | } |
442 | 18 | akiss | return K;
|
443 | 18 | akiss | } |
444 | 18 | akiss | |
445 | 18 | akiss | // Compute image laplacian
|
446 | 18 | akiss | //--------------------------------------------------------------------
|
447 | 18 | akiss | CImg<float> laplacian(CImg<float> const & img) |
448 | 18 | akiss | { |
449 | 18 | akiss | CImg<float> laplacian(img._width,img._height,img._depth,1,0); |
450 | 18 | akiss | CImg_3x3x3(I,float);
|
451 | 18 | akiss | cimg_for3x3x3(img,x,y,z,0,I,float) |
452 | 18 | akiss | { |
453 | 18 | akiss | laplacian(x,y,z) =Incc+Ipcc+Icnc+Icpc+Iccn+Iccp - 6*Iccc;
|
454 | 18 | akiss | } |
455 | 18 | akiss | return laplacian;
|
456 | 18 | akiss | } |
457 | 18 | akiss | |
458 | 18 | akiss | //Evolution AK2 contour
|
459 | 18 | akiss | //-------------------------------------------------------------------------
|
460 | 18 | akiss | CImg<float> evolution_AK2_contour(CImg<float> u, CImg<float> const & g, CImgList<float> const & gg, CImg<float> const & h, int lam, float mu, float alf, float beta, float epsilon, int dt) |
461 | 18 | akiss | { |
462 | 18 | akiss | CImg<float> diracU=Dirac(u,epsilon);
|
463 | 18 | akiss | CImgList<float> N=normal_vector(u);
|
464 | 18 | akiss | CImg<float> K=curvature2(N);
|
465 | 18 | akiss | CImg<float> L=laplacian(u);
|
466 | 18 | akiss | float term=0; |
467 | 18 | akiss | |
468 | 18 | akiss | cimg_forXYZ(u,x,y,z) |
469 | 18 | akiss | { |
470 | 18 | akiss | term=0;
|
471 | 18 | akiss | if (diracU(x,y,z)!=0) |
472 | 18 | akiss | { |
473 | 18 | akiss | //weighted length term
|
474 | 18 | akiss | if(lam!=0) |
475 | 18 | akiss | {term=( gg(0,x,y,z)*N(0,x,y,z) + gg(1,x,y,z)*N(1,x,y,z) + gg(2,x,y,z)*N(2,x,y,z) + (g(x,y,z)*K(x,y,z))) *lam;} |
476 | 18 | akiss | //length term
|
477 | 18 | akiss | if(beta!=0) |
478 | 18 | akiss | {term=term + K(x,y,z)*beta;} |
479 | 18 | akiss | //weighted area term
|
480 | 18 | akiss | if(alf!=0) |
481 | 18 | akiss | {term=term + h(x,y,z)*alf;} |
482 | 18 | akiss | //regularization
|
483 | 18 | akiss | term=term*diracU(x,y,z); |
484 | 18 | akiss | //penalizing term
|
485 | 18 | akiss | term=term + (L(x,y,z)-K(x,y,z))*mu; |
486 | 18 | akiss | } |
487 | 18 | akiss | else
|
488 | 18 | akiss | { |
489 | 18 | akiss | //penalizing term
|
490 | 18 | akiss | term=(L(x,y,z)-K(x,y,z))*mu; |
491 | 18 | akiss | } |
492 | 18 | akiss | |
493 | 18 | akiss | u(x,y,z)=u(x,y,z) + term*dt; |
494 | 18 | akiss | } |
495 | 18 | akiss | return u;
|
496 | 18 | akiss | } |
497 | 18 | akiss | |
498 | 18 | akiss | //Evolution AK2 contour cells
|
499 | 18 | akiss | //-------------------------------------------------------------------------
|
500 | 18 | akiss | CImg<float> evolution_AK2_contour_cells(CImg<float> u, CImg<float> const & g, CImgList<float> const & gg, CImg<float> const & h, int lam, float mu, float alf, int beta, float epsilon, int dt, vector<int> min_list) |
501 | 18 | akiss | { |
502 | 18 | akiss | CImg<float> diracU=Dirac(u,epsilon);
|
503 | 18 | akiss | CImgList<float> N=normal_vector(u);
|
504 | 18 | akiss | CImg<float> K=curvature2(N);
|
505 | 18 | akiss | CImg<float> L=laplacian(u);
|
506 | 18 | akiss | float term=0; |
507 | 18 | akiss | |
508 | 18 | akiss | |
509 | 18 | akiss | cimg_forXYZ(u,x,y,z) |
510 | 18 | akiss | { |
511 | 18 | akiss | int xb=x+min_list[0]; |
512 | 18 | akiss | int yb=y+min_list[1]; |
513 | 18 | akiss | int zb=z+min_list[2]; |
514 | 18 | akiss | term=0;
|
515 | 18 | akiss | if (diracU(x,y,z)!=0) |
516 | 18 | akiss | { |
517 | 18 | akiss | //weighted length term
|
518 | 18 | akiss | if(lam!=0) |
519 | 18 | akiss | {term=( gg(0,xb,yb,zb)*N(0,x,y,z) + gg(1,xb,yb,zb)*N(1,x,y,z) + gg(2,xb,yb,zb)*N(2,x,y,z) + (g(xb,yb,zb)*K(x,y,z))) *lam;} |
520 | 18 | akiss | //length term
|
521 | 18 | akiss | if(beta!=0) |
522 | 18 | akiss | {term=term + K(x,y,z)*beta;} |
523 | 18 | akiss | //weighted area term
|
524 | 18 | akiss | if(alf!=0) |
525 | 18 | akiss | {term=term + h(xb,yb,zb)*alf;} |
526 | 18 | akiss | //regularization
|
527 | 18 | akiss | term=term*diracU(x,y,z); |
528 | 18 | akiss | //penalizing term
|
529 | 18 | akiss | term=term + (L(x,y,z)-K(x,y,z))*mu; |
530 | 18 | akiss | } |
531 | 18 | akiss | else
|
532 | 18 | akiss | { |
533 | 18 | akiss | //penalizing term
|
534 | 18 | akiss | term=(L(x,y,z)-K(x,y,z))*mu; |
535 | 18 | akiss | } |
536 | 18 | akiss | |
537 | 18 | akiss | u(x,y,z)=u(x,y,z) + term*dt; |
538 | 18 | akiss | } |
539 | 18 | akiss | return u;
|
540 | 18 | akiss | } |
541 | 18 | akiss | |
542 | 18 | akiss | //Evolution AK2 contour INTERRACT
|
543 | 18 | akiss | //-------------------------------------------------------------------------
|
544 | 18 | akiss | CImg<float> evolution_AK2_contour_interact(CImg<float> u, CImg<float> const & g, CImgList<float> const & gg, CImg<float> const & h, int lam, float mu, float alf, int beta, float epsilon, int dt, CImg<unsigned char> const & free, vector<int>min_list) |
545 | 18 | akiss | { |
546 | 18 | akiss | CImg<float> diracU=Dirac(u,epsilon);
|
547 | 18 | akiss | CImgList<float> N=normal_vector(u);
|
548 | 18 | akiss | CImg<float> K=curvature2(N);
|
549 | 18 | akiss | CImg<float> L=laplacian(u);
|
550 | 18 | akiss | float term=0; |
551 | 18 | akiss | |
552 | 18 | akiss | cimg_forXYZ(u,x,y,z) |
553 | 18 | akiss | { |
554 | 18 | akiss | int xb=x+min_list[0]; |
555 | 18 | akiss | int yb=y+min_list[1]; |
556 | 18 | akiss | int zb=z+min_list[2]; |
557 | 18 | akiss | term=0;
|
558 | 18 | akiss | if(free(xb,yb,zb)==0) |
559 | 18 | akiss | { |
560 | 18 | akiss | if (diracU(x,y,z)!=0) |
561 | 18 | akiss | { |
562 | 18 | akiss | //weighted length term
|
563 | 18 | akiss | if(lam!=0) |
564 | 18 | akiss | {term=( gg(0,xb,yb,zb)*N(0,x,y,z) + gg(1,xb,yb,zb)*N(1,x,y,z) + gg(2,xb,yb,zb)*N(2,x,y,z) + (g(xb,yb,zb)*K(x,y,z))) *lam;} |
565 | 18 | akiss | //length term
|
566 | 18 | akiss | if(beta!=0) |
567 | 18 | akiss | {term=term + K(x,y,z)*beta;} |
568 | 18 | akiss | //weighted area term
|
569 | 18 | akiss | if(alf!=0) |
570 | 18 | akiss | {term=term + h(xb,yb,zb)*alf;} |
571 | 18 | akiss | //regularization
|
572 | 18 | akiss | term=term*diracU(x,y,z); |
573 | 18 | akiss | //penalizing term
|
574 | 18 | akiss | term=term + (L(x,y,z)-K(x,y,z))*mu; |
575 | 18 | akiss | } |
576 | 18 | akiss | else
|
577 | 18 | akiss | { |
578 | 18 | akiss | //penalizing term
|
579 | 18 | akiss | term=(L(x,y,z)-K(x,y,z))*mu; |
580 | 18 | akiss | } |
581 | 18 | akiss | u(x,y,z)=u(x,y,z) + term*dt; |
582 | 18 | akiss | } |
583 | 18 | akiss | } |
584 | 18 | akiss | return u;
|
585 | 18 | akiss | } |