Statistiques
| Révision :

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
}