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

Functions for setting image frame times. More...

#include "libtpcimgp.h"

Go to the source code of this file.

Functions

int imgFramesCheck (IMG *img, int verbose)
 
int imgFrameGapFill (IMG *img, int verbose)
 
int imgDeleteFrameOverlap (IMG *img)
 
int imgDeleteFrameOverlap_old (IMG *img)
 
int imgSmoothOverFrames (IMG *img, int n)
 
int imgGetFrameDiff (IMG *img, IMG *dimg, IMG *mimg, int verbose)
 
int imgGetFrameDyn (IMG *img, IMG *iimg, IMG *dimg, int verbose)
 

Detailed Description

Functions for setting image frame times.

Author
Vesa Oikonen

Definition in file imgframe.c.

Function Documentation

◆ imgDeleteFrameOverlap()

int imgDeleteFrameOverlap ( IMG * img)

Correct frame times if frames are slightly overlapping or have small gaps in between. Large gap is not corrected and it does not lead to an error.

See also
imgFramesCheck, imgFrameGapFill, imgTimeIntegral
Returns
If overlap is considerable (>1 s), or other error is encountered, function returns a non-zero value. Otherwise 0 is returned.
Parameters
imgPointer to IMG struct containing the 4D image data.

Definition at line 77 of file imgframe.c.

80 {
81 int fi;
82 float overlap, overlap_limit=1.8, flen1, flen2;
83
84 if(IMG_TEST) {fprintf(stdout, "%s()\n", __func__); fflush(stdout);}
85 if(img->status!=IMG_STATUS_OCCUPIED || img->dimt<1) return(1);
86 for(fi=0; fi<img->dimt-1; fi++) {
87 overlap=img->end[fi] - img->start[fi+1];
88 if(overlap==0.0) continue; // no gap or overlap
89 else if(overlap<-overlap_limit) continue; // gap is large, then do nothing
90 else if(overlap>overlap_limit) return(2); // overlap is large: error
91 /* Correct the small gap/overlap by making frame durations more similar */
92 flen1=img->end[fi]-img->start[fi]; flen2=img->end[fi+1]-img->start[fi+1];
93 if(overlap>0.0) { // overlap
94 if(flen1>flen2) img->end[fi]=img->start[fi+1]; else img->start[fi+1]=img->end[fi];
95 } else { // gap
96 if(flen1>flen2) img->start[fi+1]=img->end[fi]; else img->end[fi]=img->start[fi+1];
97 }
98 }
99 return(0);
100}
int IMG_TEST
Definition img.c:6
#define IMG_STATUS_OCCUPIED
char status
unsigned short int dimt
float * start
float * end

Referenced by imgReadModelingData().

◆ imgDeleteFrameOverlap_old()

int imgDeleteFrameOverlap_old ( IMG * img)

Correct frame times so that frames are not overlapping.

See also
imgDeleteFrameOverlap, imgTimeIntegral
Returns
If overlap is considerable (>1 s), or other error is encountered, function returns a non-zero value. Otherwise 0 is returned.
Parameters
imgPointer to IMG struct containing the 4D image data.

Definition at line 109 of file imgframe.c.

112 {
113 int fi;
114 float overlap;
115
116 if(IMG_TEST) {fprintf(stdout, "%s()\n", __func__); fflush(stdout);}
117 if(img->status!=IMG_STATUS_OCCUPIED || img->dimt<1) return(1);
118 for(fi=0; fi<img->dimt-1; fi++) {
119 overlap=img->end[fi] - img->start[fi+1];
120 if(overlap==0.0) continue;
121 else if(overlap>1.0) return(2);
122 img->end[fi]=img->start[fi+1];
123 }
124 return(0);
125}

◆ imgFrameGapFill()

int imgFrameGapFill ( IMG * img,
int verbose )

Fill gaps between time frames by extending adjacent frames over the gap. Overlaps, and gap before the first frame is ignored.

See also
imgFramesCheck, imgDeleteFrameOverlap, imgExistentTimes, imgTimeIntegral
Returns
0 if successful, >0 in case of an error.
Parameters
imgPointer to IMG struct containing the 4D image data.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 50 of file imgframe.c.

55 {
56 if(verbose>0) {printf("%s(*img)\n", __func__); fflush(stdout);}
57 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED || img->dimt<2) return(0);
58
59 for(int fi=1; fi<img->dimt; fi++) {
60 float gap=img->start[fi] - img->end[fi-1];
61 if(gap<1.0E-07) continue;
62 if(verbose>2) printf("gap between frames %d and %d: %g\n", fi, fi+1, gap);
63 img->start[fi] -= 0.5*gap; img->mid[fi]=0.5*(img->start[fi]+img->end[fi]);
64 img->end[fi-1]=img->start[fi]; img->mid[fi-1]=0.5*(img->start[fi-1]+img->end[fi-1]);
65 }
66 return(0);
67}
float * mid

◆ imgFramesCheck()

int imgFramesCheck ( IMG * img,
int verbose )

Check for gaps or overlap between frame times. Gap before the first frame is ignored.

See also
imgExistentTimes, imgDeleteFrameOverlap, imgTimeIntegral, imgFrameGapFill
Returns
0, if no overlaps or gaps are found, 1 if overlaps are found, 2 if gaps are found, and 3 if both overlaps and gaps are found.
Parameters
imgPointer to IMG struct containing the 4D image data. Data is not modified.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 15 of file imgframe.c.

20 {
21 if(verbose>0) {printf("%s(*img)\n", __func__); fflush(stdout);}
22 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED || img->dimt<2) return(0);
23
24 int gapNr=0, overlapNr=0;
25 for(int fi=1; fi<img->dimt; fi++) {
26 float gap=img->start[fi] - img->end[fi-1];
27 if(verbose>2 && fabs(gap)>1.0E-06)
28 printf("gap between frames %d and %d: %g\n", fi, fi+1, gap);
29 if(gap>1.0E-06) gapNr++;
30 else if(gap<-1.0E-06) overlapNr++;
31 }
32 if(verbose>1) {
33 printf(" %d overlap(s)\n", overlapNr);
34 printf(" %d gap(s)\n", gapNr);
35 fflush(stdout);
36 }
37 int ret=0;
38 if(overlapNr>0) ret+=1;
39 if(gapNr>0) ret+=2;
40 return(ret);
41}

Referenced by imgAUMC(), and imgMRT().

◆ imgGetFrameDiff()

int imgGetFrameDiff ( IMG * img,
IMG * dimg,
IMG * mimg,
int verbose )

Compute sum absolute difference and/or sum absolute average between consecutive frames.

See also
imgGetPeak, imgGetMaxFrame, imgSmoothOverFrames
Returns
Returns 0, if ok.
Parameters
imgDynamic image; not modified.
dimgPointer to an empty IMG struct in which the sum of absolute differences will be written; any old contents are deleted; NULL, if not needed.
mimgPointer to an empty IMG struct in which the sum of absolute means will be written; any old contents are deleted; NULL, if not needed.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 180 of file imgframe.c.

191 {
192 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
193
194 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) return(1);
195 if(img->dimt<2) {
196 if(verbose>0) {fprintf(stderr, "only dynamic image can be processed!\n"); fflush(stderr);}
197 return(1);
198 }
199 if(dimg==NULL && mimg==NULL) return(0);
200 if(dimg!=NULL && dimg->status==IMG_STATUS_OCCUPIED) imgEmpty(dimg);
201 if(mimg!=NULL && mimg->status==IMG_STATUS_OCCUPIED) imgEmpty(mimg);
202
203
204 /* Allocate memory for one frame */
205 int ret=0;
206 if(verbose>1) {
207 printf("allocating memory for %dx%dx%d pixels\n", img->dimz, img->dimy, img->dimx);
208 fflush(stdout);
209 }
210 if(dimg!=NULL) ret=imgAllocate(dimg, img->dimz, img->dimy, img->dimx, 1); else ret=0;
211 if(!ret && mimg!=NULL) ret=imgAllocate(mimg, img->dimz, img->dimy, img->dimx, 1);
212 if(ret) return(ret);
213 /* set image header information */
214 if(dimg!=NULL) {
215 imgCopyhdr(img, dimg);
216 dimg->start[0]=img->start[0]; dimg->end[0]=img->end[img->dimt-1];
217 dimg->mid[0]=(dimg->start[0]+dimg->end[0])/2.0;
218 }
219 if(mimg!=NULL) {
220 imgCopyhdr(img, mimg);
221 mimg->start[0]=img->start[0]; mimg->end[0]=img->end[img->dimt-1];
222 mimg->mid[0]=(mimg->start[0]+mimg->end[0])/2.0;
223 }
224
225 /* Go through every pixel */
226 int ti, zi, xi, yi;
227 for(zi=0; zi<img->dimz; zi++) {
228 for(yi=0; yi<img->dimy; yi++) for(xi=0; xi<img->dimx; xi++) {
229 for(ti=1; ti<img->dimt; ti++) {
230 if(dimg!=NULL) {
231 dimg->m[zi][yi][xi][0]+=fabs(img->m[zi][yi][xi][ti]-img->m[zi][yi][xi][ti-1]);
232 }
233 if(mimg!=NULL) {
234 mimg->m[zi][yi][xi][0]+=0.5*fabs(img->m[zi][yi][xi][ti]+img->m[zi][yi][xi][ti-1]);
235 }
236 }
237 }
238 }
239
240 return(0);
241}
int imgAllocate(IMG *image, int planes, int rows, int columns, int frames)
Definition img.c:194
int imgCopyhdr(IMG *image1, IMG *image2)
Definition img.c:471
void imgEmpty(IMG *image)
Definition img.c:121
unsigned short int dimx
float **** m
unsigned short int dimz
unsigned short int dimy

◆ imgGetFrameDyn()

int imgGetFrameDyn ( IMG * img,
IMG * iimg,
IMG * dimg,
int verbose )

Compute the number of increases and decreases between consecutive frames.

See also
imgGetPeak, imgGetMaxFrame
Returns
Returns 0, if ok.
Parameters
imgDynamic image; not modified.
iimgPointer to an empty IMG struct in which the nr of increases will be written; any old contents are deleted; NULL, if not needed.
dimgPointer to an empty IMG struct in which the nr of decreases will be written; any old contents are deleted; NULL, if not needed.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 249 of file imgframe.c.

260 {
261 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
262
263 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) return(1);
264 if(img->dimt<2) {
265 if(verbose>0) {fprintf(stderr, "only dynamic image can be processed!\n"); fflush(stderr);}
266 return(1);
267 }
268 if(iimg==NULL && dimg==NULL) return(0);
269 if(iimg!=NULL && iimg->status==IMG_STATUS_OCCUPIED) imgEmpty(iimg);
270 if(dimg!=NULL && dimg->status==IMG_STATUS_OCCUPIED) imgEmpty(dimg);
271
272
273 /* Allocate memory for one frame */
274 int ret=0;
275 if(verbose>1) {
276 printf("allocating memory for %dx%dx%d pixels\n", img->dimz, img->dimy, img->dimx);
277 fflush(stdout);
278 }
279 if(dimg!=NULL) ret=imgAllocate(dimg, img->dimz, img->dimy, img->dimx, 1); else ret=0;
280 if(!ret && iimg!=NULL) ret=imgAllocate(iimg, img->dimz, img->dimy, img->dimx, 1);
281 if(ret) return(ret);
282 /* set image header information */
283 if(dimg!=NULL) {
284 imgCopyhdr(img, dimg);
285 dimg->start[0]=img->start[0]; dimg->end[0]=img->end[img->dimt-1];
286 dimg->mid[0]=(dimg->start[0]+dimg->end[0])/2.0;
287 }
288 if(iimg!=NULL) {
289 imgCopyhdr(img, iimg);
290 iimg->start[0]=img->start[0]; iimg->end[0]=img->end[img->dimt-1];
291 iimg->mid[0]=(iimg->start[0]+iimg->end[0])/2.0;
292 }
293 iimg->unit=dimg->unit=CUNIT_UNITLESS;
294
295 /* Go through every pixel */
296 int ti, zi, xi, yi;
297 if(iimg!=NULL) {
298 for(zi=0; zi<img->dimz; zi++) {
299 for(yi=0; yi<img->dimy; yi++) for(xi=0; xi<img->dimx; xi++) {
300 for(ti=1; ti<img->dimt; ti++)
301 if(img->m[zi][yi][xi][ti]>img->m[zi][yi][xi][ti-1]) iimg->m[zi][yi][xi][0]+=1.0;
302 if(verbose>2) {printf("increases m[%d][%d][%d]=%g\n", zi, yi, xi, iimg->m[zi][yi][xi][0]);}
303 }
304 }
305 }
306 if(dimg!=NULL) {
307 for(zi=0; zi<img->dimz; zi++) {
308 for(yi=0; yi<img->dimy; yi++) for(xi=0; xi<img->dimx; xi++) {
309 for(ti=1; ti<img->dimt; ti++)
310 if(img->m[zi][yi][xi][ti]<img->m[zi][yi][xi][ti-1]) dimg->m[zi][yi][xi][0]+=1.0;
311 if(verbose>2) {printf("decreases m[%d][%d][%d]=%g\n", zi, yi, xi, dimg->m[zi][yi][xi][0]);}
312 }
313 }
314 }
315
316 return(0);
317}
char unit

◆ imgSmoothOverFrames()

int imgSmoothOverFrames ( IMG * img,
int n )

Smooth dynamic image data over specified number of time frames.

Average is weighted by frame durations. Gaps or overlaps in frame times are not taken into account. Do not use this for quantitative analysis, but only for robust peak search etc.

See also
imgGetFrameDiff, imgGaussianFilter, imgMeanFilter, imgMeanZ
Returns
Non-zero value, if error is encountered, otherwise 0 is returned.
Parameters
imgPointer to IMG structure containing the 4D image data.
nNr of frames to average; n must be an odd number and at least 3.

Definition at line 136 of file imgframe.c.

141 {
142 int zi, yi, xi, fi, fj, m, f1, f2;
143
144 if(IMG_TEST) {fprintf(stdout, "%s(img, %d)\n", __func__, n); fflush(stdout);}
145 if(img->status!=IMG_STATUS_OCCUPIED) return(1);
146 if(n<3) n=3; else if((n%2)==0) return(1);
147 if(img->dimt<n) return(0); // too few frames for smoothing
148 m=n/2;
149 double orig[img->dimt], vsum, fsum, fdur;
150 for(zi=0; zi<img->dimz; zi++) {
151 for(yi=0; yi<img->dimy; yi++) for(xi=0; xi<img->dimx; xi++) {
152 /* preserve original data for now */
153 for(fi=0; fi<img->dimt; fi++) orig[fi]=img->m[zi][yi][xi][fi];
154 /* frame-by-frame */
155 for(fi=0; fi<img->dimt; fi++) {
156 /* set frame range */
157 f1=fi-m; if(f1<0) f1=0;
158 f2=fi+m; if(f2>img->dimt-1) f2=img->dimt-1;
159 /* mean */
160 fsum=vsum=0.0;
161 for(fj=f1; fj<=f2; fj++) {
162 fdur=img->end[fj]-img->start[fj];
163 vsum+=fdur*orig[fj];
164 fsum+=fdur;
165 }
166 if(fsum<1.0E-010) return(2);
167 img->m[zi][yi][xi][fi]=vsum/fsum;
168 }
169 }
170 }
171 return(0);
172}