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