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