26 #define Malloc(s) malloc(s)
27 #define Free(p) free(p)
29 #define DIVIDE_EPS ((num)1e-16)
33 #define M_PI 3.14159265358979323846264338327950288
47 int (*PlotFun)(int, int, num,
const num*,
const num*,
const num*,
48 int, int, int,
void*);
53 int ChanVeseSimplePlot(
int State,
int Iter, num Delta,
54 const num *c1,
const num *c2,
55 __attribute__((unused))
const num *Phi,
56 __attribute__((unused))
int Width,
57 __attribute__((unused))
int Height,
59 __attribute__((unused))
void *Param);
61 int ChanVeseSimplePlot(
int State,
int Iter, num Delta,
62 const num *c1,
const num *c2,
72 {(num)1e-3, 500, (num)0.25, 0, 1, 1, (num)0.5,
73 ChanVeseSimplePlot, NULL};
128 int Width,
int Height,
int NumChannels,
const chanveseopt *Opt)
130 int (*PlotFun)(int, int, num,
const num*,
const num*,
const num*,
131 int, int, int,
void*);
132 const long NumPixels = ((long)Width) * ((long)Height);
133 const long NumEl = NumPixels * NumChannels;
134 const num *fPtr, *fPtr2;
135 double PhiDiffNorm, PhiDiff;
136 num *PhiPtr, *c1 = 0, *c2 = 0;
137 num c1Scalar, c2Scalar, Mu, Nu, Lambda1, Lambda2, dt;
138 num PhiLast, Delta, PhiX, PhiY, IDivU, IDivD, IDivL, IDivR;
139 num Temp1, Temp2, Dist1, Dist2, PhiTol;
140 int Iter, i, j, Channel, MaxIter, Success = 2;
143 if(!Phi || !f || Width <= 0 || Height <= 0 || NumChannels <= 0)
151 Lambda1 = Opt->Lambda1;
152 Lambda2 = Opt->Lambda2;
154 MaxIter = Opt->MaxIter;
155 PlotFun = Opt->PlotFun;
157 PhiDiffNorm = (PhiTol > 0) ? PhiTol*1000 : 1000;
161 if(!(c1 =
Malloc(
sizeof(num)*NumChannels))
162 || !(c2 =
Malloc(
sizeof(num)*NumChannels)))
174 if(!PlotFun(0, 0, PhiDiffNorm, c1, c2, Phi,
175 Width, Height, NumChannels, Opt->PlotParam))
178 for(Iter = 1; Iter <= MaxIter; Iter++)
184 for(j = 0; j < Height; j++)
186 iu = (j == 0) ? 0 : -Width;
187 id = (j == Height - 1) ? 0 : Width;
189 for(i = 0; i < Width; i++, PhiPtr++, fPtr++)
191 il = (i == 0) ? 0 : -1;
192 ir = (i == Width - 1) ? 0 : 1;
194 Delta = dt/(
M_PI*(1 + PhiPtr[0]*PhiPtr[0]));
195 PhiX = PhiPtr[ir] - PhiPtr[0];
196 PhiY = (PhiPtr[id] - PhiPtr[iu])/2;
197 IDivR = (num)(1/sqrt(DIVIDE_EPS + PhiX*PhiX + PhiY*PhiY));
198 PhiX = PhiPtr[0] - PhiPtr[il];
199 IDivL = (num)(1/sqrt(DIVIDE_EPS + PhiX*PhiX + PhiY*PhiY));
200 PhiX = (PhiPtr[ir] - PhiPtr[il])/2;
201 PhiY = PhiPtr[id] - PhiPtr[0];
202 IDivD = (num)(1/sqrt(DIVIDE_EPS + PhiX*PhiX + PhiY*PhiY));
203 PhiY = PhiPtr[0] - PhiPtr[iu];
204 IDivU = (num)(1/sqrt(DIVIDE_EPS + PhiX*PhiX + PhiY*PhiY));
208 Dist1 = fPtr[0] - c1Scalar;
209 Dist2 = fPtr[0] - c2Scalar;
217 for(Channel = 0, fPtr2 = fPtr;
218 Channel < NumChannels; Channel++, fPtr2 += NumPixels)
220 Temp1 = fPtr2[0] - c1[Channel];
221 Temp2 = fPtr2[0] - c2[Channel];
222 Dist1 += Temp1*Temp1;
223 Dist2 += Temp2*Temp2;
229 PhiPtr[0] = (PhiPtr[0] + Delta*(
230 Mu*(PhiPtr[ir]*IDivR + PhiPtr[il]*IDivL
231 + PhiPtr[id]*IDivD + PhiPtr[iu]*IDivU)
232 - Nu - Lambda1*Dist1 + Lambda2*Dist2) ) /
233 (1 + Delta*Mu*(IDivR + IDivL + IDivD + IDivU));
234 PhiDiff = (PhiPtr[0] - PhiLast);
235 PhiDiffNorm += PhiDiff * PhiDiff;
239 PhiDiffNorm = sqrt(PhiDiffNorm/NumEl);
242 if(Iter >= 2 && PhiDiffNorm <= PhiTol)
246 if(!PlotFun(0, Iter, PhiDiffNorm, c1, c2, Phi,
247 Width, Height, NumChannels, Opt->PlotParam))
251 Success = (Iter <= MaxIter) ? 1:2;
254 PlotFun(Success, (Iter <= MaxIter) ? Iter:MaxIter,
255 PhiDiffNorm, c1, c2, Phi,
256 Width, Height, NumChannels, Opt->PlotParam);
274 for(j = 0; j < Height; j++)
275 for(i = 0; i < Width; i++)
276 *(Phi++) = (num)(sin(i*
M_PI/5.0)*sin(j*
M_PI/5.0));
282 int Width,
int Height,
int NumChannels)
284 const long NumPixels = ((long)Width) * ((long)Height);
285 num Sum1 = 0, Sum2 = 0;
287 long Count1 = 0, Count2 = 0;
290 for(Channel = 0; Channel < NumChannels; Channel++, f += NumPixels)
292 for(n = 0; n < NumPixels; n++)
304 c1[Channel] = (Count1) ? (Sum1/Count1) : 0;
305 c2[Channel] = (Count2) ? (Sum2/Count2) : 0;
315 int ChanVeseSimplePlot(
int State,
int Iter, num Delta,
316 const num *c1,
const num *c2,
317 __attribute__((unused))
const num *Phi,
318 __attribute__((unused))
int Width,
319 __attribute__((unused))
int Height,
321 __attribute__((unused))
void *Param)
323 int ChanVeseSimplePlot(
int State,
int Iter, num Delta,
324 const num *c1,
const num *c2,
341 fprintf(stderr,
" Iteration %4d Delta %7.4f c1 = %6.4f c2 = %6.4f\r",
342 Iter, Delta, *c1, *c2);
344 fprintf(stderr,
" Iteration %4d Delta %7.4f\r", Iter, Delta);
347 fprintf(stderr,
"Converged in %d iterations. \n",
351 fprintf(stderr,
"Maximum number of iterations exceeded. \n");
408 Opt->Lambda1 = Lambda1;
416 Opt->Lambda2 = Lambda2;
440 Opt->MaxIter = MaxIter;
484 int (*PlotFun)(
int,
int, num,
const num*,
const num*,
const num*,
485 int,
int,
int,
void*),
void *PlotParam)
489 Opt->PlotFun = PlotFun;
490 Opt->PlotParam = PlotParam;
500 printf(
"tol : %g\n", Opt->Tol);
501 printf(
"max iter : %d\n", Opt->MaxIter);
502 printf(
"mu : %g\n", Opt->Mu);
503 printf(
"nu : %g\n", Opt->Nu);
504 printf(
"lambda1 : %g\n", Opt->Lambda1);
505 printf(
"lambda2 : %g\n", Opt->Lambda2);
506 printf(
"dt : %g\n", Opt->dt);