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