TPCCLIB
Loading...
Searching...
No Matches
imgsegm.c File Reference

Functions for segmentation of 4D PET images. More...

#include "libtpcimgp.h"

Go to the source code of this file.

Functions

int imgsegmThresholdMask (IMG *img, float minValue, float maxValue, IMG *timg)
 
int imgsegmThresholdByMask (IMG *img, IMG *template, float minValue, float maxValue)
 
int imgsegmThreshold (IMG *img, float minValue, float maxValue)
 
int imgsegmMaskToCluster (IMG *img)
 
int imgsegmFindMaxOutsideClusters (IMG *sumimg, IMG *cluster, float *max, int *plane, int *row, int *col)
 
int imgsegmClusterExpand (IMG *cimg, IMG *simg, IMG *dimg, int clusterID, int pi, int ri, int ci, int pj, int rj, int cj, float CVlim, float CClim, int verbose)
 
float imgsegmPearson (float *x, float *y, long long nr)
 
int imgsegmClusterMean (IMG *dimg, IMG *cimg, int clusterID, float *avg, int verbose)
 
int imgsegmCheckNeighbours (IMG *cimg, int pi, int ri, int ci)
 
int imgsegmFindBestNeighbour (IMG *dimg, IMG *cimg, int pi, int ri, int ci)
 
int imgsegmSimilar (IMG *input, int smoothDim, int smoothNr, IMG *output, int verbose)
 
int imgsegmCalcMRL (float y1[], float y2[], long long n)
 

Detailed Description

Functions for segmentation of 4D PET images.

Author
Vesa Oikonen

Definition in file imgsegm.c.

Function Documentation

◆ imgsegmCalcMRL()

int imgsegmCalcMRL ( float y1[],
float y2[],
long long n )

Calculates the maximum run length between given n length arrays of data.

See also
imgsegmPearson, imgsegmSimilar, imgsegmFindBestNeighbour, imgThresholdingLowHigh
Returns
Returns the maximum run length between given n length arrays of data.
Parameters
y1Array 1.
y2Array 2.
nLength of arrays.

Definition at line 567 of file imgsegm.c.

574 {
575 long long i, mrl=0, rl=0;
576 char last_sign=0, sign;
577
578 for(i=0; i<n; i++) {
579 if(y1[i]>y2[i]) sign=1; else if(y1[i]<y2[i]) sign=-1; else sign=0;
580 if(sign!=last_sign) {
581 rl=0; last_sign=sign;
582 } else {
583 if(sign!=0) {rl++; if(rl>mrl) mrl=rl;}
584 }
585 }
586 return(mrl);
587}

Referenced by imgsegmSimilar().

◆ imgsegmCheckNeighbours()

int imgsegmCheckNeighbours ( IMG * cimg,
int pi,
int ri,
int ci )

Checks if neighbours of the specified pixel belong to any cluster.

See also
imgsegmFindBestNeighbour
Returns
Returns 1, if all are in clusters, and 0, if at least one is 'free'.
Parameters
cimgCluster image.
piPixel definition [z,y,x].
riPixel definition [z,y,x].
ciPixel definition [z,y,x].

Definition at line 398 of file imgsegm.c.

407 {
408 int pj, rj, cj;
409
410 for(pj=pi-1; pj<=pi+1; pj++) if(pj>=0 && pj<cimg->dimz)
411 for(rj=ri-1; rj<=ri+1; rj++) if(rj>=0 && rj<cimg->dimy)
412 for(cj=ci-1; cj<=ci+1; cj++) if(cj>=0 && cj<cimg->dimx)
413 if((pi!=pj || ri!=rj || ci!=cj) && cimg->m[pj][rj][cj][0]<-0.1) return(0);
414 return(1);
415}
float **** m

◆ imgsegmClusterExpand()

int imgsegmClusterExpand ( IMG * cimg,
IMG * simg,
IMG * dimg,
int clusterID,
int pi,
int ri,
int ci,
int pj,
int rj,
int cj,
float CVlim,
float CClim,
int verbose )

Expands the cluster locally to its neighbour pixels.

Calls itself recursively until neighbouring pixels do not belong to cluster. Because of recursion, program which uses this function needs a large space for stack: add the following line to your program: unsigned _stklen = 4194304;

See also
imgMaskErode, imgMaskDilate
Returns
Returns 0, if test pixel belongs to cluster, and 1 if not, and >1 in case of an error.
Parameters
cimgpointer to cluster image data.
simgpointer to sum image data.
dimgpointer to dynamic image data.
clusterIDnumber of cluster to be tested.
picoordinates of test pixel [z,y,x].
ricoordinates of test pixel [z,y,x].
cicoordinates of test pixel [z,y,x].
pjcoordinates of cluster start [z,y,x].
rjcoordinates of cluster start [z,y,x].
cjcoordinates of cluster start [z,y,x].
CVlimCV limit.
CClimCC limit.
verboseVerbose level; if zero, then only warnings are printed into stderr.

Definition at line 219 of file imgsegm.c.

246 {
247 if(verbose>0) {
248 printf("imgsegmClusterExpand(cimg, simg, dimg, %d, %d, %d, %d, %d, %d, %d, %f, %f, %d)\n",
249 clusterID, pi, ri, ci, pj, rj, cj, CVlim, CClim, verbose);
250 fflush(stdout);
251 }
252 if(cimg==NULL || cimg->status!=IMG_STATUS_OCCUPIED) return(2);
253 if(simg==NULL || simg->status!=IMG_STATUS_OCCUPIED) return(3);
254 if(dimg==NULL || dimg->status!=IMG_STATUS_OCCUPIED) return(4);
255
256 /* Check that test pixel resides inside image volume */
257 if(pi<0 || ri<0 || ci<0 || pi>=cimg->dimz || ri>=cimg->dimy || ci>=cimg->dimx) {
258 if(verbose>1) printf("pixels does not reside inside image\n");
259 return(1);
260 }
261
262 /* Check that test pixel is not already part of any cluster */
263 if(cimg->m[pi][ri][ci][0]>=-0.1) {
264 if(verbose>1)
265 printf("pixel already belongs to cluster %g\n", cimg->m[pi][ri][ci][0]);
266 return(1);
267 }
268
269 /* Check that AUCs are matching */
270 {
271 float mean=0.5*(simg->m[pi][ri][ci][0]+simg->m[pj][rj][cj][0]);
272 float a=simg->m[pi][ri][ci][0]-mean;
273 float b=simg->m[pj][rj][cj][0]-mean;
274 float cv;
275 if(fabs(mean)>1.0e-10) cv=(a*a + b*b) / mean; else cv=0.0;
276 if(verbose>2) printf("cv=%g CVlim=%g mean=%g\n", cv, CVlim, mean);
277 if(cv>CVlim) {
278 if(verbose>2) printf("AUCs are not matching, %g>%g\n", cv, CVlim);
279 return(1);
280 }
281 }
282
283 /* Check that TACs are correlating */
284 {
285 float r=imgsegmPearson(dimg->m[pj][rj][cj], dimg->m[pi][ri][ci], dimg->dimt);
286 if(verbose>3) printf(" r=%g CClim=%g\n", r, CClim);
287 if(r<CClim) {
288 if(verbose>2) printf("TACs are not correlating, %g<%g\n", r, CClim);
289 return(1);
290 }
291 }
292
293 /* If we got this far, the test pixel belongs to the cluster */
294 cimg->m[pi][ri][ci][0]=clusterID;
295 if(verbose>1) {
296 printf(" [%d][%d][%d] belongs to cluster %d\n", pi, ri, ci, clusterID);
297 fflush(stdout);
298 }
299
300 /* Check if the neighbouring pixels belong to this cluster */
301 for(int pk=pi-1; pk<=pi+1; pk++) if(pk>=0 && pk<cimg->dimz)
302 for(int rk=ri-1; rk<=ri+1; rk++) if(rk>=0 && rk<cimg->dimy)
303 for(int ck=ci-1; ck<=ci+1; ck++) if(ck>=0 && ck<cimg->dimx)
304 if((pk!=pi || rk!=ri || ck!=ci) && cimg->m[pk][rk][ck][0]<-0.1) {
305 int ret=imgsegmClusterExpand(cimg, simg, dimg, clusterID,
306 pk, rk, ck, pj, rj, cj, CVlim, CClim, verbose);
307 if(ret>1) return(ret);
308 }
309
310 return(0);
311}
float imgsegmPearson(float *x, float *y, long long nr)
Definition imgsegm.c:322
int imgsegmClusterExpand(IMG *cimg, IMG *simg, IMG *dimg, int clusterID, int pi, int ri, int ci, int pj, int rj, int cj, float CVlim, float CClim, int verbose)
Definition imgsegm.c:219
#define IMG_STATUS_OCCUPIED
int mean(double *x, double *y, int nr, double *xmean, double *xsd, double *ymean, double *ysd)
Definition pearson.c:341
unsigned short int dimx
char status
unsigned short int dimt
unsigned short int dimz
unsigned short int dimy

Referenced by imgsegmClusterExpand().

◆ imgsegmClusterMean()

int imgsegmClusterMean ( IMG * dimg,
IMG * cimg,
int clusterID,
float * avg,
int verbose )

Calculates the average of pixels belonging to the specified cluster, and returns this average for each frame in the specified float array.

Cluster pixels do not have to be adjacent!

See also
imgsegmSimilar
Returns
Returns the nr of pixels that belong to this cluster, or <0 in case of an error.
Parameters
dimgDynamic image.
cimgCluster image.
clusterIDCluster number 0...
avgPointer to a float array where cluster average TAC is written.
verboseVerbose level; if zero, then only warnings are printed into stderr.

Definition at line 357 of file imgsegm.c.

368 {
369 int fi, pi, ri, ci;
370
371 /* Check the arguments */
372 if(dimg==NULL || cimg==NULL || avg==NULL) return(-1);
373 if(cimg->dimx!=dimg->dimx || cimg->dimy!=dimg->dimy || cimg->dimz!=dimg->dimz)
374 return(-2);
375
376 if(verbose>0) printf("calculating avg of cluster %d:", clusterID);
377 for(fi=0; fi<dimg->dimt; fi++) avg[fi]=0.0;
378 long long n=0;
379 for(pi=0; pi<cimg->dimz; pi++)
380 for(ri=0; ri<cimg->dimy; ri++)
381 for(ci=0; ci<cimg->dimx; ci++)
382 if(fabs(cimg->m[pi][ri][ci][0]-(float)clusterID)<0.1) {
383 for(fi=0; fi<dimg->dimt; fi++)
384 avg[fi]+=dimg->m[pi][ri][ci][fi];
385 n++;
386 }
387 if(n>0) for(fi=0; fi<dimg->dimt; fi++) avg[fi]/=(float)n;
388 if(verbose>0) printf(" %lld pixels\n", n);
389 return(n);
390}

Referenced by clusterTACs().

◆ imgsegmFindBestNeighbour()

int imgsegmFindBestNeighbour ( IMG * dimg,
IMG * cimg,
int pi,
int ri,
int ci )

Combines this pixel to the cluster of the neighbour which has the best correlation.

All neighbours of the specified pixel must belong to some cluster (must be checked before calling this function).

See also
imgsegmCalcMRL, imgsegmCheckNeighbours
Returns
If ok, returns 0.
Parameters
dimgDynamic image.
cimgCluster image.
piPixel definition [z,y,x].
riPixel definition [z,y,x].
ciPixel definition [z,y,x].

Definition at line 427 of file imgsegm.c.

438 {
439 int pj, rj, cj;
440 float cc, best_cc, best_ID;
441
442 best_ID=-1.0; best_cc=-1.0e+20;
443 for(pj=pi-1; pj<=pi+1; pj++) if(pj>=0 && pj<cimg->dimz)
444 for(rj=ri-1; rj<=ri+1; rj++) if(rj>=0 && rj<cimg->dimy)
445 for(cj=ci-1; cj<=ci+1; cj++) if(cj>=0 && cj<cimg->dimx)
446 if((pi!=pj || ri!=rj || ci!=cj)) {
447 cc=imgsegmPearson(dimg->m[pj][rj][cj], dimg->m[pi][ri][ci], dimg->dimt);
448 if(cc>best_cc) {
449 best_cc=cc;
450 best_ID=cimg->m[pj][rj][cj][0];
451 }
452 }
453 if(best_ID<0.0) return(1);
454 cimg->m[pi][ri][ci][0]=best_ID;
455 return(0);
456}

◆ imgsegmFindMaxOutsideClusters()

int imgsegmFindMaxOutsideClusters ( IMG * sumimg,
IMG * cluster,
float * max,
int * plane,
int * row,
int * col )

Finds the maximum sumimg pixel value, excluding all pixels which already belong to clusters (cluster>=0).

Returns
Returns 0, if max was found, >1 in case of an error, and -1, if all pixels already belong to clusters.
Parameters
sumimgIntegral image.
clusterCluster image.
maxFound max value.
planeFound max pixel [Z,y,x].
rowFound max pixel [z,Y,x].
colFound max pixel [z,y,X].

Definition at line 166 of file imgsegm.c.

179 {
180 int p, i, j, maxp=0, maxi=0, maxj=0;
181
182 if(sumimg->status!=IMG_STATUS_OCCUPIED) return(1);
183 if(cluster->status!=IMG_STATUS_OCCUPIED) return(2);
184 if(sumimg->dimt>1) return(3);
185 if(cluster->dimt>1) return(4);
186 if(sumimg->dimx!=cluster->dimx || sumimg->dimy!=cluster->dimy) return(5);
187 if(sumimg->dimz!=cluster->dimz) return(6);
188
189 *max=-1.0e8;
190 long long n=0;
191 for(p=0; p<sumimg->dimz; p++) {
192 for(j=0; j<sumimg->dimy; j++) for(i=0; i<sumimg->dimx; i++)
193 if(cluster->m[p][j][i][0]<-0.1) {
194 if(sumimg->m[p][j][i][0]>*max) {
195 *max=sumimg->m[p][j][i][0]; maxp=p; maxj=j; maxi=i;
196 }
197 n++;
198 }
199 }
200 if(n==0) return(-1);
201 *plane=maxp; *row=maxj; *col=maxi;
202 return(0);
203}

◆ imgsegmMaskToCluster()

int imgsegmMaskToCluster ( IMG * img)

Sets 0 values in mask image to -1, and others to value 0.

Returns
Returns 0 if ok.
Parameters
imgPointer to the mask image.

Definition at line 142 of file imgsegm.c.

145 {
146 int plane, i, j;
147
148 if(img->status!=IMG_STATUS_OCCUPIED) return(1);
149 if(img->dimt>1) return(2);
150 for(plane=0; plane<img->dimz; plane++)
151 for(j=0; j<img->dimy; j++) for(i=0; i<img->dimx; i++) {
152 if(img->m[plane][j][i][0]>0.0) img->m[plane][j][i][0]=0.0;
153 else img->m[plane][j][i][0]=-1.0;
154 }
155 return(0);
156}

◆ imgsegmPearson()

float imgsegmPearson ( float * x,
float * y,
long long nr )

Calculates Pearson's correlation coefficient between x[] and y[] values.

Not corrected for sample size.

See also
regr_line, best_pearson, highest_slope, pearson, mean, imgsegmCalcMRL
Returns
Returns Pearson's correlation coefficient; in case of an error returns 0.
Parameters
xx axis values.
yy axis values.
nrnr of samples.

Definition at line 322 of file imgsegm.c.

329 {
330 int i;
331 float sumx=0.0, sumy=0.0, sumsx=0.0, sumsy=0.0, sumxy=0.0, r, q;
332
333 if(nr<1 || x==NULL || y==NULL) return(0.0);
334 if(nr<3) return(1.0);
335 for(i=0; i<nr; i++) {
336 sumx+=x[i]; sumy+=y[i];
337 sumsx+=x[i]*x[i]; sumsy+=y[i]*y[i];
338 sumxy+=x[i]*y[i];
339 }
340 q=(sumsx - sumx*sumx/(float)nr) * (sumsy - sumy*sumy/(float)nr);
341 if(q<=0.0) return(1.0);
342 r=(sumxy-((sumx*sumy)/(float)nr)) / sqrt(q);
343 return(r);
344}

Referenced by imgsegmClusterExpand(), and imgsegmFindBestNeighbour().

◆ imgsegmSimilar()

int imgsegmSimilar ( IMG * input,
int smoothDim,
int smoothNr,
IMG * output,
int verbose )

Computes a smoothed image from the specified dynamic image with noise.

The TACs inside a matrix smoothDim*smoothDim*smoothDim are sorted by the MRL and AUC, and each TAC is replaced by the mean of the best smoothNr TACs. This function allocates memory for output and copies the header info.

See also
imgsegmCalcMRL, imgsegmFindBestNeighbour, imgFast3DGaussianFilter, imgAverageTAC
Returns
Returns 0 if ok.
Parameters
inputDynamic input image.
smoothDimSmoothing mask dimensions; either 3 or 5 (default).
smoothNrNr of TACs to average; default is 9.
outputSmoothed image.
verboseVerbose level; if zero, then only warnings are printed into stderr.

Definition at line 478 of file imgsegm.c.

489 {
490 int ret, pi, ri, ci, pj, rj, cj, mi, mj, fi, maskNr, smod;
491 IMG sum;
492 IMGSEGMMASK mask[125];
493
494
495 if(verbose>0) printf("in filterSimilar(input, %d, %d, output)\n", smoothDim, smoothNr);
496 /* Check the parameters */
497 if(input->status!=IMG_STATUS_OCCUPIED) return(1);
498 if(input->dimt<2) return(2);
499 if(smoothDim==3) smod=1; else smod=2;
500 if(smoothNr<2) smoothNr=9;
501
502 /* Compute AUC image */
503 imgInit(&sum);
504 ret=imgFrameIntegral(input, 0, input->dimt-1, &sum, verbose);
505 if(ret) return(10+ret);
506
507 /* Allocate space for smoothed image */
509 output, input->dimz, input->dimy, input->dimx, input->dimt, input);
510 if(ret) {imgEmpty(&sum); return(20+ret);}
511
512 /* One pixel at a time */
513 for(pi=0; pi<input->dimz; pi++) {
514 if(input->dimz>1) {fprintf(stdout, "."); fflush(stdout);}
515 for(ri=0; ri<input->dimy; ri++) {
516 for(ci=0; ci<input->dimx; ci++) {
517 /* Fill the smoothing mask values */
518 for(mi=0; mi<125; mi++) mask[mi].order=0;
519 mi=0;
520 for(pj=pi-smod; pj<=pi+smod; pj++) if(pj>=0 && pj<input->dimz) {
521 for(rj=ri-smod; rj<=ri+smod; rj++) if(rj>=0 && rj<input->dimy) {
522 for(cj=ci-smod; cj<=ci+smod; cj++) if(cj>=0 && cj<input->dimx) {
523 mask[mi].p=pj; mask[mi].r=rj; mask[mi].c=cj;
524 /* Calculate the AUC difference */
525 mask[mi].dauc=fabs(sum.m[pi][ri][ci][0]-sum.m[pj][rj][cj][0]);
526 /* Calculate the MRL */
527 mask[mi].mrl=imgsegmCalcMRL(input->m[pi][ri][ci], input->m[pj][rj][cj], input->dimt);
528 mi++;
529 }
530 }
531 }
532 maskNr=mi;
533 /* Put mask values in similarity order */
534 for(mi=0; mi<maskNr; mi++) {
535 mask[mi].order=0;
536 for(mj=0; mj<maskNr; mj++) {
537 if(mask[mj].dauc>mask[mi].dauc) mask[mi].order++;
538 if(mask[mj].mrl>mask[mi].mrl) mask[mi].order++;
539 }
540 }
541 qsort(mask, maskNr, sizeof(IMGSEGMMASK), imgsegmSimilarSort);
542 /* Calculate average */
543 mj=smoothNr; if(mj>maskNr/2) mj=maskNr/2;
544 for(fi=0; fi<input->dimt; fi++) {
545 output->m[pi][ri][ci][fi]=0.0;
546 for(mi=0; mi<mj; mi++) {
547 /*printf("order=%d pj=%d rj=%d cj=%d\n", mask[mi].order, mask[mi].p, mask[mi].r, mask[mi].c);*/
548 output->m[pi][ri][ci][fi]+=
549 input->m[mask[mi].p][mask[mi].r][mask[mi].c][fi];
550 }
551 output->m[pi][ri][ci][fi]/=(double)mj;
552 }
553 }
554 }
555 }
556 if(input->dimz>1) {fprintf(stdout, "\n"); fflush(stdout);}
557 imgEmpty(&sum);
558 return(0);
559}
int imgAllocateWithHeader(IMG *image, int planes, int rows, int columns, int frames, IMG *image_from)
Definition img.c:279
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgFrameIntegral(IMG *img, int first, int last, IMG *iimg, int verbose)
Definition imgarithm.c:346
int imgsegmCalcMRL(float y1[], float y2[], long long n)
Definition imgsegm.c:567

◆ imgsegmThreshold()

int imgsegmThreshold ( IMG * img,
float minValue,
float maxValue )

Sets values <minValue to zero, and values >maxValue to maxValue.

See also
imgThresholdingLowHigh, imgsegmThresholdByMask
Returns
Returns 0 if ok.
Parameters
imgDynamic or static image.
minValueMin pixel value.
maxValueMax pixel value.

Definition at line 116 of file imgsegm.c.

123 {
124 int frame, plane, i, j;
125
126 if(img->status!=IMG_STATUS_OCCUPIED) return(1);
127 for(plane=0; plane<img->dimz; plane++)
128 for(j=0; j<img->dimy; j++) for(i=0; i<img->dimx; i++)
129 for(frame=0; frame<img->dimt; frame++)
130 if(img->m[plane][j][i][frame]<minValue)
131 img->m[plane][j][i][frame]=0.0;
132 else if(img->m[plane][j][i][frame]>maxValue)
133 img->m[plane][j][i][frame]=maxValue;
134 return(0);
135}

◆ imgsegmThresholdByMask()

int imgsegmThresholdByMask ( IMG * img,
IMG * template,
float minValue,
float maxValue )

Sets pixel values in img to minValue, if corresponding pixel value in the mask is == 2, and to maxValue, if mask value is == 1.

Only first plane of the mask is used.

See also
imgThresholdingLowHigh, imgsegmThreshold, imgThresholdMaskCount
Returns
Returns 0 if ok.
Parameters
imgDynamic image which is modified based on the mask.
templateMask image.
minValueThis value is put into img if template value is =2.
maxValueThis value is put into img if template value is =1.

Definition at line 83 of file imgsegm.c.

92 {
93 int frame, plane, i, j;
94
95 if(img->status!=IMG_STATUS_OCCUPIED) return(1);
96 if(template->status!=IMG_STATUS_OCCUPIED) return(2);
97 for(plane=0; plane<img->dimz; plane++)
98 for(j=0; j<img->dimy; j++) for(i=0; i<img->dimx; i++)
99 if(template->m[plane][j][i][0]==1.0) {
100 for(frame=0; frame<img->dimt; frame++)
101 img->m[plane][j][i][frame]=minValue;
102 } else if(template->m[plane][j][i][0]==2.0) {
103 for(frame=0; frame<img->dimt; frame++)
104 img->m[plane][j][i][frame]=maxValue;
105 }
106 return(0);
107}

◆ imgsegmThresholdMask()

int imgsegmThresholdMask ( IMG * img,
float minValue,
float maxValue,
IMG * timg )

Allocate and fill a mask image based on the specified image and threshold values.

If pixel value in original image is <minValue, sets the mask pixel to 1, if >maxValue, sets mask pixel to 2, and to 0, if value is between minValue and maxValue. Only first frame is used, allocated and filled.

See also
imgVoiMaskTAC, imgMaskTAC, imgThresholdMaskCount, imgMaskDilate, imgMaskErode
Returns
Returns 0 if ok.
Parameters
imgPointer to original (static) image.
minValueLower threshold limit.
maxValueUpper threshold limit.
timgPointer to initiated and empty mask image.

Definition at line 39 of file imgsegm.c.

48 {
49 int frame, plane, i, j, ret;
50
51 if(img->status!=IMG_STATUS_OCCUPIED) return(1);
52 /* Allocate memory for the mask data */
53 ret=imgAllocateWithHeader(timg, img->dimz, img->dimy, img->dimx, 1, img);
54 if(ret) return(ret);
55 timg->start[0]=img->start[0]; timg->end[0]=img->end[img->dimt-1];
56 timg->mid[0]=(timg->start[0]+timg->end[0])/2.0;
57 timg->isWeight=0;
58
59 /* Make the mask data */
60 for(plane=0; plane<img->dimz; plane++)
61 for(j=0; j<img->dimy; j++) for(i=0; i<img->dimx; i++) {
62 frame=0;
63 if(img->m[plane][j][i][frame]<minValue)
64 timg->m[plane][j][i][frame]=1.0;
65 else if(img->m[plane][j][i][frame]>maxValue)
66 timg->m[plane][j][i][frame]=2.0;
67 else
68 timg->m[plane][j][i][frame]=0.0;
69 }
70 return(0);
71}
float * start
float * end
float * mid
char isWeight