Statistiques
| Révision :

root / bin / lsm_lib.h @ 18

Historique | Voir | Annoter | Télécharger (16,48 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
//Add black slices on each side of the image
17
//----------------------------------------------------------------------------
18
CImg<float> add_side_slices(CImg<float> const & img, int side)
19
{
20
  int s=side*2;
21
  CImg<float> newImg(img._width+s,img._height+s,img._depth+s,1,1);
22

    
23
  cimg_forXYZ(img,x,y,z)
24
    {
25
      newImg(x+side,y+side,z+side)=img(x,y,z);   
26
    }
27
  return newImg;
28
}
29

    
30
//Remove slices
31
//----------------------------------------------------------------------------
32
CImg<float> remove_side_slices(CImg<float> const & img, int side)
33
{
34
  int s=side*2;
35
  CImg<float> newImg(img._width-s,img._height-s,img._depth-s,1,0);
36

    
37
  cimg_forXYZ(newImg,x,y,z)
38
    {
39
      newImg(x,y,z)=img(x+side,y+side,z+side);   
40
    }
41
  return newImg;
42
}
43

    
44
//Threshold linear along Z   1:background  0:cells
45
//----------------------------------------------------------------------------
46
CImg<unsigned char> threshold_linear_alongZ(CImg<float> const & img, int t1, int t2)
47
{
48
  CImg<unsigned char> outside(img._width,img._height,img._depth,1,0);
49
  for(int z=0; z<img._depth ; z++)
50
    {
51
      cimg_forXY(outside,x,y)
52
        {
53
          float thresh = t1 + (t2-t1)*(z*1.0/img._depth);
54
          if(img(x,y,z)<thresh)
55
            {outside(x,y,z)=1;}        
56
        }
57
    }
58
  outside.label();
59
  cimg_forXYZ(outside,x,y,z)
60
    {
61
      if(outside(x,y,z)>0) {outside(x,y,z)=0;}
62
      else {outside(x,y,z)=1;}
63
    }
64
  return outside;
65
}
66

    
67
//LSM contour init +c0 background, -c0 cells
68
//--------------------------------------------------------------------------
69
CImg<float> lsm_contour_init(CImg<unsigned char> const & region,int c0)
70
{
71
  CImg<float> initLSM(region._width,region._height,region._depth,1,c0);
72
  initLSM=initLSM-2*c0*region;
73
  return initLSM;
74
}
75

    
76
//Gradient 3D with central finite differences
77
//----------------------------------------------------------------------------
78
CImgList<float> gradient(CImg<float> const & img)
79
{
80
  //List of 3 images the same size as img
81
  CImgList<float> grad(3,img._width,img._height,img._depth,1,0);
82

    
83
  //Image loop with a 3*3*3 neighborhood
84
  CImg_3x3x3(I,float);
85
  cimg_for3x3x3(img,x,y,z,0,I,float)
86
    {
87
      grad(0,x,y,z) = (Incc - Ipcc)/2; //grad x = (img(x+1,y,z)-img(x-1,y,z))/2
88
      grad(1,x,y,z) = (Icnc - Icpc)/2; //grad y
89
      grad(2,x,y,z) = (Iccn - Iccp)/2; //grad z
90
    }
91
  return grad;
92
}
93

    
94
//Norm of the gradient
95
//---------------------------------------------------------------------------
96
CImg<float> gradient_norm(CImg<float> const & img)
97
{
98
  CImgList<float> grad = gradient(img);
99
  CImg<float> res(grad[0]._width,grad[0]._height,grad[0]._depth,1,0);
100
  float f=0;
101
  cimg_forXYZ(res,x,y,z)
102
    {
103
      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
      res(x,y,z)=sqrt(f);
105
    }
106
  return res;
107
}
108

    
109

    
110
//Edge indicator
111
//---------------------------------------------------------------------------
112
CImg<float> edge_indicator(CImgList<float> const & grad)
113
{
114
  CImg<float> res(grad[0]._width,grad[0]._height,grad[0]._depth,1,0);
115
  float f=0;
116
  cimg_forXYZ(res,x,y,z)
117
    {
118
      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
      res(x,y,z)=1.0/(1.0+f);
120
      //res(x,y,z)=exp(-f);
121
    }
122
  return res;
123
}
124

    
125
//Edge indicator 1 (gradient)
126
//---------------------------------------------------------------------------
127
CImg<float> edge_indicator1(CImg<float> const & img)
128
{
129
  CImgList<float> grad;
130
  grad = gradient(img);
131
  CImg<float> res(img._width,img._height,img._depth,1,0);
132
  float f=0;
133
  cimg_forXYZ(res,x,y,z)
134
    {
135
      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
      res(x,y,z)=1.0/(1.0+f);
137
    }
138
  return res;
139
}
140

    
141
CImg<float> edge_indicator1(CImg<float> const & img, float gamma)
142
{
143
  CImgList<float> grad;
144
  grad = gradient(img);
145
  CImg<float> res(img._width,img._height,img._depth,1,0);
146
  float f=0;
147
  cimg_forXYZ(res,x,y,z)
148
    {
149
      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
      res(x,y,z)=1.0/(1.0+f/gamma/gamma);
151
    }
152
  return res;
153
}
154

    
155
//Edge indicator 2 (hessienne, computed without smoothing)
156
//---------------------------------------------------------------------------
157
CImg<float> edge_indicator2(CImg<float> const & img)
158
{
159
  CImg<float> res(img._width,img._height,img._depth,1,0); 
160
  float f=0;
161
  cimg_forXYZ(res,x,y,z)
162
    {
163
    int xp=x-1;
164
        if (x==0){xp=x;}
165
        int xn=x+1;
166
        if (x==img._width-1){xn=x;}
167
        int yp=y-1;
168
        if (y==0){yp=y;}
169
        int yn=y+1;
170
        if (y==img._height-1){yn=y;}
171
        int zp=z-1;
172
        if (z==0){zp=z;}
173
        int zn=z+1;
174
        if (z==img._depth-1){zn=z;}
175

    
176
        CImg<float> hess(3,3,1,1,0);
177
        hess(0,0) = img(xp,y,z) + img(xn,y,z) - 2*img(x,y,z);          // Hxx
178
        hess(1,1) = img(x,yp,z) + img(x,yn,z) - 2*img(x,y,z);          // Hyy
179
        hess(2,2) = img(x,y,zp) + img(x,y,zn) - 2*img(x,y,z);          // Hzz
180
        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
        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
        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
        
184
        //val : 3 eigen values as an array, decreasing order
185
        //vec : 3 eigen vectors as a 3*3 image
186
        //have to be double or create NaN
187
        CImg<double> val,vec;
188
        hess.symmetric_eigen(val,vec);
189
        if (val[2]>0) val[2]=0;
190
        val[2]=-val[2];
191
        //res(x,y,z)=1.0/(1.0 +val[2]*(50/3.));  //h=g test4
192
    //res(x,y,z)=1.0/(1.0 +val[2]*val[2]*(50/3.)*(50/3.) );
193
    //res(x,y,z)=1.0/(1.0 +exp(-val[2]));
194
    //res(x,y,z)=exp(-val[2]);
195
    //res(x,y,z)=exp(-val[2]*val[2]);
196
    res(x,y,z)=1.0/(1.0 +val[2]*val[2]);
197
    }
198
  return res;
199
}
200

    
201
//Edge indicator 2 (hessienne, computed with smoothing)
202
//---------------------------------------------------------------------------
203
CImg<float> edge_indicator2s(CImg<float> const & img, float gamma)
204
{
205
  CImg<float> res(img._width,img._height,img._depth,1,0);
206
    
207
  // make a minimal blur before taking derivatives
208
  CImg<float> imgBlur=img.get_blur(2);
209
  
210
  float f=0;
211
  cimg_forXYZ(res,x,y,z)
212
    {
213
    int xp=x-1;
214
        if (x==0){xp=x;}
215
        int xn=x+1;
216
        if (x==img._width-1){xn=x;}
217
        int yp=y-1;
218
        if (y==0){yp=y;}
219
        int yn=y+1;
220
        if (y==img._height-1){yn=y;}
221
        int zp=z-1;
222
        if (z==0){zp=z;}
223
        int zn=z+1;
224
        if (z==img._depth-1){zn=z;}
225

    
226
        CImg<float> hess(3,3,1,1,0);
227
        hess(0,0) = imgBlur(xp,y,z) + imgBlur(xn,y,z) - 2*imgBlur(x,y,z);          // Hxx
228
        hess(1,1) = imgBlur(x,yp,z) + imgBlur(x,yn,z) - 2*imgBlur(x,y,z);          // Hyy
229
        hess(2,2) = imgBlur(x,y,zp) + imgBlur(x,y,zn) - 2*imgBlur(x,y,z);          // Hzz
230
        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
        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
        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
        
234
        //val : 3 eigen values as an array, decreasing order
235
        //vec : 3 eigen vectors as a 3*3 image
236
        //have to be double or create NaN
237
        CImg<double> val,vec;
238
        hess.symmetric_eigen(val,vec);
239
        if (val[2]>0) val[2]=0;
240
        val[2]=-val[2];
241
    res(x,y,z)=1.0/(1.0 +val[2]*val[2]/gamma/gamma);
242
    }
243
  return res;
244
}
245

    
246

    
247
CImg<float> edge_indicator2(CImg<float> const & img, float gamma)
248
{
249
  CImg<float> res(img._width,img._height,img._depth,1,0);
250
  float f=0;
251
  cimg_forXYZ(res,x,y,z)
252
    {
253
    int xp=x-1;
254
        if (x==0){xp=x;}
255
        int xn=x+1;
256
        if (x==img._width-1){xn=x;}
257
        int yp=y-1;
258
        if (y==0){yp=y;}
259
        int yn=y+1;
260
        if (y==img._height-1){yn=y;}
261
        int zp=z-1;
262
        if (z==0){zp=z;}
263
        int zn=z+1;
264
        if (z==img._depth-1){zn=z;}
265

    
266
        CImg<float> hess(3,3,1,1,0);
267
        hess(0,0) = img(xp,y,z) + img(xn,y,z) - 2*img(x,y,z);          // Hxx
268
        hess(1,1) = img(x,yp,z) + img(x,yn,z) - 2*img(x,y,z);          // Hyy
269
        hess(2,2) = img(x,y,zp) + img(x,y,zn) - 2*img(x,y,z);          // Hzz
270
        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
        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
        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
        
274
        //val : 3 eigen values as an array, decreasing order
275
        //vec : 3 eigen vectors as a 3*3 image
276
        //have to be double or create NaN
277
        CImg<double> val,vec;
278
        hess.symmetric_eigen(val,vec);
279
        if (val[2]>0) val[2]=0;
280
        //val[2]=-val[2];
281
    res(x,y,z)=1.0/(1.0 +val[2]*val[2]/gamma/gamma);
282
    }
283
  return res;
284
}
285

    
286
//Edge indicator 3 (image based)
287
//---------------------------------------------------------------------------
288
CImg<float> edge_indicator3(CImg<float> const & img)
289
{
290
  CImg<float> res(img._width,img._height,img._depth,1,0);
291
  cimg_forXYZ(res,x,y,z)
292
    {
293
      res(x,y,z)=1.0/(1.0+img(x,y,z)*img(x,y,z));
294
    }
295
  return res;
296
}
297

    
298
CImg<float> edge_indicator3(CImg<float> const & img, float gamma)
299
{
300
  CImg<float> res(img._width,img._height,img._depth,1,0);
301
  cimg_forXYZ(res,x,y,z)
302
    {
303
                res(x,y,z)=1.0/(1.0+(img(x,y,z)/gamma)*(img(x,y,z)/gamma));
304
    }
305
  return res;
306
}
307

    
308
//Edge image (based on lambda3 of the hessien)
309
//---------------------------------------------------------------------------
310
CImg<float> edge_lambda3(CImg<float> const & img)
311
{
312
  CImg<float> res(img._width,img._height,img._depth,1,0);
313
  float f=0;
314
  cimg_forXYZ(res,x,y,z)
315
    {
316
    int xp=x-1;
317
        if (x==0){xp=x;}
318
        int xn=x+1;
319
        if (x==img._width-1){xn=x;}
320
        int yp=y-1;
321
        if (y==0){yp=y;}
322
        int yn=y+1;
323
        if (y==img._height-1){yn=y;}
324
        int zp=z-1;
325
        if (z==0){zp=z;}
326
        int zn=z+1;
327
        if (z==img._depth-1){zn=z;}
328

    
329
        CImg<float> hess(3,3,1,1,0);
330
        hess(0,0) = img(xp,y,z) + img(xn,y,z) - 2*img(x,y,z);          // Hxx
331
        hess(1,1) = img(x,yp,z) + img(x,yn,z) - 2*img(x,y,z);          // Hyy
332
        hess(2,2) = img(x,y,zp) + img(x,y,zn) - 2*img(x,y,z);          // Hzz
333
        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
        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
        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
        
337
        //val : 3 eigen values as an array, decreasing order
338
        //vec : 3 eigen vectors as a 3*3 image
339
        //have to be double or create NaN
340
        CImg<double> val,vec;
341
        hess.symmetric_eigen(val,vec);
342
        if (val[2]>0) val[2]=0;
343
    res(x,y,z)=-val[2];
344
    }
345
  return res;
346
}
347

    
348

    
349
//Wall indicator
350
//---------------------------------------------------------------------------
351
CImg<float> wall_indicator(CImg<float> const & img)
352
{
353
  CImg<float> res(img._width,img._height,img._depth,1,0);
354
  cimg_forXYZ(res,x,y,z)
355
    {
356
      res(x,y,z)=1.0/(1.0+(img(x,y,z)*img(x,y,z)));
357
    }
358
  return res;
359
}
360

    
361
//Dirac function
362
//-------------------------------------------------------------------------
363
CImg<float> Dirac(CImg<float> const & img, float sigma)
364
{
365
  CImg<float> fImg(img._width,img._height,img._depth,1,0);
366
  float f=0;
367
  cimg_forXYZ(img,x,y,z)
368
    {
369
      if(abs(img(x,y,z))<=sigma)
370
        {
371
          f=(1.0/(2*sigma))*(1+cos(M_PI*img(x,y,z)/sigma));
372
        }
373
      else {f=0;}
374
      fImg(x,y,z)=f;
375
    }
376
  return fImg;
377
} 
378

    
379
//Normal vector
380
//------------------------------------------------------------------------
381
CImgList<float> normal_vector(CImg<float> const & img)
382
{
383
  CImgList<float> normal_vector(3,img._width,img._height,img._depth,1,0); 
384

    
385
  CImg_3x3x3(I,float);        
386
  cimg_for3x3x3(img,x,y,z,0,I,float) 
387
    {
388
      float nx = (Incc-Ipcc)/2.0;    
389
      float ny = (Icnc-Icpc)/2.0;   
390
      float nz = (Iccn-Iccp)/2.0;
391
      //border
392
      if((x==0)or(y==0)or(z==0))
393
        {nx=ny=nz=0;}
394
      if((x==img.width()-1)or(y==img.height()-1)or(z==img.depth()-1))
395
        {nx=ny=nz=0;}
396

    
397
      float norm=1;
398
      if((nx!=0)or(ny!=0)or(nz!=0))
399
        {norm = sqrt(nx*nx+ny*ny+nz*nz);}
400
 
401
      normal_vector(0,x,y,z)=nx/norm;
402
      normal_vector(1,x,y,z)=ny/norm;
403
      normal_vector(2,x,y,z)=nz/norm;
404
    }
405
  return normal_vector;
406
}
407

    
408

    
409
//Curvature
410
//------------------------------------------------------------------------
411
CImg<float> curvature2(CImgList<float> const & N)
412
{
413
  CImg<float> K(N[0]._width,N[0]._height,N[0]._depth,1,0);
414
  cimg_forXYZ(N[0],x,y,z)
415
    {
416
      float kx=0;
417
      float ky=0;
418
      float kz=0;
419
      if(x==0)
420
        {kx=N[0](x+1,y,z)-N[0](x,y,z);}
421
      else if(x==N[0]._width-1)
422
        {kx=N[0](x,y,z)-N[0](x-1,y,z);}
423
      else
424
        {kx=(N[0](x+1,y,z)-N[0](x-1,y,z))/2.0;}
425

    
426
     if(y==0)
427
        {ky=N[1](x,y+1,z)-N[1](x,y,z);}
428
      else if(y==N[1]._height-1)
429
        {ky=N[1](x,y,z)-N[1](x,y-1,z);}
430
      else
431
        {ky=(N[1](x,y+1,z)-N[1](x,y-1,z))/2.0;}
432

    
433
     if(z==0)
434
        {kz=N[2](x,y,z+1)-N[2](x,y,z);}
435
      else if(z==N[2]._depth-1)
436
        {kz=N[2](x,y,z)-N[2](x,y,z-1);}
437
      else
438
        {kz=(N[2](x,y,z+1)-N[2](x,y,z-1))/2.0;}
439

    
440
     K(x,y,z)=kx+ky+kz;
441
    }
442
  return K;
443
}
444

    
445
// Compute image laplacian
446
//--------------------------------------------------------------------
447
CImg<float> laplacian(CImg<float> const & img)
448
{
449
  CImg<float> laplacian(img._width,img._height,img._depth,1,0);
450
  CImg_3x3x3(I,float);
451
  cimg_for3x3x3(img,x,y,z,0,I,float)
452
    {
453
      laplacian(x,y,z) =Incc+Ipcc+Icnc+Icpc+Iccn+Iccp - 6*Iccc;
454
    }
455
  return laplacian;
456
}
457

    
458
//Evolution AK2 contour
459
//-------------------------------------------------------------------------
460
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
{
462
  CImg<float> diracU=Dirac(u,epsilon); 
463
  CImgList<float> N=normal_vector(u);
464
  CImg<float> K=curvature2(N);
465
  CImg<float> L=laplacian(u);
466
  float term=0;
467

    
468
  cimg_forXYZ(u,x,y,z)
469
    {
470
      term=0;
471
      if (diracU(x,y,z)!=0)
472
        {
473
          //weighted length term
474
          if(lam!=0)
475
            {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
          //length term
477
          if(beta!=0)
478
            {term=term + K(x,y,z)*beta;}
479
          //weighted area term
480
          if(alf!=0)
481
            {term=term + h(x,y,z)*alf;}
482
          //regularization
483
          term=term*diracU(x,y,z);
484
          //penalizing term
485
          term=term + (L(x,y,z)-K(x,y,z))*mu;
486
        }
487
      else
488
        {
489
          //penalizing term
490
          term=(L(x,y,z)-K(x,y,z))*mu;
491
        }
492
      
493
      u(x,y,z)=u(x,y,z) + term*dt;
494
    }
495
  return u;
496
}
497

    
498
//Evolution AK2 contour cells
499
//-------------------------------------------------------------------------
500
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
{
502
  CImg<float> diracU=Dirac(u,epsilon); 
503
  CImgList<float> N=normal_vector(u);
504
  CImg<float> K=curvature2(N);
505
  CImg<float> L=laplacian(u);
506
  float term=0;
507

    
508

    
509
  cimg_forXYZ(u,x,y,z)
510
    {
511
      int xb=x+min_list[0];
512
      int yb=y+min_list[1];
513
      int zb=z+min_list[2];
514
      term=0;
515
      if (diracU(x,y,z)!=0)
516
        {
517
          //weighted length term
518
          if(lam!=0)
519
            {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
          //length term
521
          if(beta!=0)
522
            {term=term + K(x,y,z)*beta;}
523
          //weighted area term
524
          if(alf!=0)
525
            {term=term + h(xb,yb,zb)*alf;}            
526
          //regularization
527
          term=term*diracU(x,y,z);
528
          //penalizing term
529
          term=term + (L(x,y,z)-K(x,y,z))*mu;
530
        }
531
      else
532
        {
533
          //penalizing term
534
          term=(L(x,y,z)-K(x,y,z))*mu;
535
        }
536
      
537
      u(x,y,z)=u(x,y,z) + term*dt;
538
    }
539
  return u;
540
}
541

    
542
//Evolution AK2 contour INTERRACT
543
//-------------------------------------------------------------------------
544
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
{
546
  CImg<float> diracU=Dirac(u,epsilon); 
547
  CImgList<float> N=normal_vector(u);
548
  CImg<float> K=curvature2(N);
549
  CImg<float> L=laplacian(u);
550
  float term=0;
551

    
552
  cimg_forXYZ(u,x,y,z)
553
    {
554
      int xb=x+min_list[0];
555
      int yb=y+min_list[1];
556
      int zb=z+min_list[2];
557
      term=0;
558
      if(free(xb,yb,zb)==0)
559
        {
560
          if (diracU(x,y,z)!=0)
561
            {
562
              //weighted length term
563
              if(lam!=0)
564
                {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
              //length term
566
              if(beta!=0)
567
                {term=term + K(x,y,z)*beta;}
568
              //weighted area term
569
              if(alf!=0)
570
                {term=term + h(xb,yb,zb)*alf;}
571
              //regularization
572
              term=term*diracU(x,y,z);
573
              //penalizing term
574
              term=term + (L(x,y,z)-K(x,y,z))*mu;
575
            }
576
          else
577
            {
578
              //penalizing term
579
              term=(L(x,y,z)-K(x,y,z))*mu;
580
            }        
581
          u(x,y,z)=u(x,y,z) + term*dt;
582
        }
583
    }
584
  return u;
585
}