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

Image transformation functions. More...

#include "libtpcimgp.h"

Go to the source code of this file.

Functions

int img2cube (IMG *img1, int dim, IMG *img2)
void imgScale (IMG *src, IMG *targ, float zoom, int method)
void integerScale (int frame, float ***src, float **targ, int width, int height, int zoom)
int imgSwell (IMG *img1, IMG *img2, int doz)
int imgShrink (IMG *img1, IMG *img2, int doz)

Detailed Description

Image transformation functions.

Author
Calle Laakkonen, Jarkko Johansson, Vesa Oikonen

Definition in file imgtransform.c.

Function Documentation

◆ img2cube()

int img2cube ( IMG * img1,
int dim,
IMG * img2 )

Resample image to cubic image volume, where all three dimensions are the same, with cubic voxel sizes. Note that some smoothing occurs in the process, therefore the use of this function should be limited to illustrations of image data.

See also
imgFlipHorizontal, imgFlipVertical, imgFlipAbove, imgScale, imgSwell, imgShrink
Returns
Returns 0 if successful, otherwise <>0.
Parameters
img1Pointer to IMG to be resliced; this image is not modified.
dimNew dimension; enter 0 to use the largest dimension in image.
img2Pointer to initiated IMG where resliced data will be stored.

Definition at line 16 of file imgtransform.c.

23 {
24 int ret, n, testf;
25 int xi, yi, zi, xj, yj, zj, fi, xp, yp, zp;
26 double xsize, ysize, zsize, newsize;
27 double xdist, ydist, zdist;
28 double xpc, ypc, zpc, xd, yd, zd;
29 double w, wsum, d;
30
31 if(IMG_TEST>0) printf("img2cube(img1, img2)\n");
32 if(img1->status!=IMG_STATUS_OCCUPIED) return(1);
33 if(img2->status==IMG_STATUS_OCCUPIED) imgEmpty(img2);
34
35 if(IMG_TEST>1)
36 printf("original dimensions (x,y,z) := %d,%d,%d\n", img1->dimx, img1->dimy, img1->dimz);
37 if(dim<1) {
38 /* Get the largest dimension of original image volume */
39 dim=img1->dimz; n=0;
40 if(img1->dimx>dim) {dim=img1->dimx; n++;}
41 if(img1->dimy>dim) {dim=img1->dimy; n++;}
42 }
43 if(IMG_TEST>1) printf("new dimensions (x,y,z) := %d,%d,%d\n", dim, dim, dim);
44 testf=dim*dim*dim/10;
45
46 /* Allocate memory for the new IMG */
47 ret=imgAllocate(img2, dim, dim, dim, img1->dimt);
48 if(ret) return(10+ret);
49 imgCopyhdr(img1, img2);
50
51 /* Calculate the physical extensions of original image volume */
52 xsize=img1->dimx*(img1->sizex + img1->gapx);
53 ysize=img1->dimy*(img1->sizey + img1->gapy);
54 zsize=img1->dimz*(img1->sizez + img1->gapz);
55 if(IMG_TEST>1) printf("original image size (x,y,z) in mm := %g,%g,%g\n", xsize, ysize, zsize);
56 /* New image volume will be a cube of highest size of those */
57 newsize=xsize; n=0;
58 if(ysize>newsize) {newsize=ysize; n++;}
59 if(zsize>newsize) {newsize=zsize; n++;}
60 if(IMG_TEST>1) {
61 printf("original image size (x,y,z) in mm := %g,%g,%g\n",
62 xsize, ysize, zsize);
63 if(n>0) printf("new image size (x,y,z) in mm:= %g,%g,%g\n",
64 newsize, newsize, newsize);
65 else printf("original image size needs not to be changed.\n");
66 }
67 img2->gapx=img2->gapy=img2->gapz=0.0;
68 img2->sizex=img2->sizey=img2->sizez=newsize/(double)dim;
69
70 /* Resample the image volume */
71 n=0;
72 for(zj=0; zj<dim; zj++) for(yj=0; yj<dim; yj++) for(xj=0; xj<dim; xj++) {
73 if(IMG_TEST>3 && n%testf==0) printf("zj=%d yj=%d xj=%d\n", zj, yj, xj);
74 /* Calculate the distance of this voxel from the mid of new image volume */
75 xdist=((double)xj+0.5)*img2->sizex - 0.5*newsize;
76 ydist=((double)yj+0.5)*img2->sizey - 0.5*newsize;
77 zdist=((double)zj+0.5)*img2->sizez - 0.5*newsize;
78 if(IMG_TEST>3 && n%testf==0)
79 printf(" xdist=%g ydist=%g zdist=%g\n", xdist, ydist, zdist);
80 /* The place in coordinates of original image */
81 xpc=(0.5*xsize+xdist)/(img1->sizex + img1->gapx);
82 ypc=(0.5*ysize+ydist)/(img1->sizey + img1->gapy);
83 zpc=(0.5*zsize+zdist)/(img1->sizez + img1->gapz);
84 /* Inside which voxel it resides? */
85 xp=(int)(xpc+0.5); yp=(int)(ypc+0.5); zp=(int)(zpc+0.5);
86 if(IMG_TEST>3 && n%testf==0)
87 printf(" inside pixel %d,%d,%d\n", xp, yp, zp);
88 /* Calculate 1/distance-weighted average of 3x3x3 pixels around it */
89 for(fi=0; fi<img1->dimt; fi++) img2->m[zj][yj][xj][fi]=0.0;
90 wsum=0.0;
91 for(zi=zp-1; zi<=zp+1; zi++)
92 for(yi=yp-1; yi<=yp+1; yi++) for(xi=xp-1; xi<=xp+1; xi++) {
93 /* Distance between voxels */
94 xd=(0.5+xi)-xpc; yd=(0.5+yi)-ypc; zd=(0.5+zi)-zpc;
95 d=xd*xd+yd*yd+zd*zd; //if(d>0.0) d=sqrt(d); else d=0.0;
96 if(IMG_TEST>3 && n%testf==0)
97 printf(" distance^2 from (%d,%d,%d) := %g\n", xi, yi, zi, d);
98 /* Add weight to the weight sum */
99 w=exp(-d); wsum+=w;
100 if(IMG_TEST>3 && n%testf==0) printf(" weight := %g\n", w);
101 /* If voxel is inside the image, add value to the sum */
102 if(zi>=0 && yi>=0 && xi>=0 && zi<img1->dimz && yi<img1->dimy && xi<img1->dimx) {
103 for(fi=0; fi<img1->dimt; fi++) {
104 img2->m[zj][yj][xj][fi]+=w*img1->m[zi][yi][xi][fi];
105 }
106 }
107 }
108 /* Divide the sum with sum weight */
109 for(fi=0; fi<img1->dimt; fi++) img2->m[zj][yj][xj][fi]/=wsum;
110 if(IMG_TEST>3 && n%testf==0)
111 printf(" weighted avg in 1st frame := %g\n", img2->m[zj][yj][xj][0]);
112 n++;
113 }
114
115 return 0;
116}
int IMG_TEST
Definition img.c:6
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
#define IMG_STATUS_OCCUPIED
float sizex
unsigned short int dimx
float gapx
float **** m
char status
unsigned short int dimt
float sizey
unsigned short int dimz
unsigned short int dimy
float gapy
float gapz
float sizez

◆ imgScale()

void imgScale ( IMG * src,
IMG * targ,
float zoom,
int method )

Image size scaling using the defined method.

See also
integerScale, imgArithm, imgSwell, imgShrink
Parameters
srcSource image to be scaled.
targScaled image; must be allocated to the size of resulting image.
zoomScaling factor (integer); currently must be >=1.
methodMethod code number (not used yet).

Definition at line 123 of file imgtransform.c.

132 {
133 int frame, plane, x, y;
134 float **tmp_targ;
135
136 if(method==0) {} // prevent compiler warning
137
138 // Allocate memory for temporary target matrix:
139 tmp_targ = malloc(targ->dimy * sizeof(float*));
140 for(y=0; y<targ->dimy; y++)
141 tmp_targ[y] = malloc(targ->dimx * sizeof(float));
142
143 for(plane=0; plane<src->dimz; plane++)
144 for(frame=0; frame<src->dimt; frame++){
145 integerScale(frame, src->m[plane], tmp_targ, src->dimx, src->dimy, (int)roundf(zoom));
146 // Copy scaled image matrix to target image buffer:
147 for(y=0; y<targ->dimy; y++)
148 for(x=0; x<targ->dimx; x++)
149 targ->m[plane][y][x][frame] = tmp_targ[y][x];
150 }
151}
void integerScale(int frame, float ***src, float **targ, int width, int height, int zoom)

◆ imgShrink()

int imgShrink ( IMG * img1,
IMG * img2,
int doz )

Shrink the image data matrix into half of the original size in each dimension.

Eight neighbouring pixels are averaged into one pixel, without any interpolation etc.

See also
img2cube, imgScale, imgSwell, imgMaskErode
Returns
Returns 0 if ok.
Parameters
img1Pointer to the original image; not changed.
img2Pointer to the shrunken image; must be initiated. If allocated for correct size, then only pixel values are set; if not, then any previous contents are deleted, memory is allocated, header information is set, and of course the pixel values are set.
dozShrink (1) the image in z dimension (over image planes), or shrink only in x and y dimensions (0).

Definition at line 263 of file imgtransform.c.

274 {
275 if(img1==NULL || img2==NULL) return(1);
276 if(img1->dimz<1 || img1->dimy<2 || img1->dimx<2 || img1->dimt<1) return(2);
277
278 /* Set correct dimensions for the shrunken image */
279 int dimz, dimy, dimx;
280 if(doz!=0) dimz=0.5*img1->dimz; else dimz=img1->dimz;
281 dimy=0.5*img1->dimy;
282 dimx=0.5*img1->dimx;
283 /* Correct dimensions (add 1) if the original ones were odd */
284 if((img1->dimz % 2!=0.0) && doz!=0) dimz+=1;
285 if(img1->dimy % 2!=0.0) dimy+=1;
286 if(img1->dimx % 2!=0.0) dimx+=1;
287
288 /* If output image does not yet have these dimensions, then re-allocate it and set headers */
289 if(img2->dimz!=dimz || img2->dimy!=dimy || img2->dimx!=dimx || img2->dimt!=img1->dimt) {
290 /* Allocate memory for the image */
291 int ret=imgAllocateWithHeader(img2, dimz, dimy, dimx, img1->dimt, img1);
292 if(ret) return(10+ret);
293 /* Correct the pixel sizes so that the actual size (cm x cm) of the image won't change */
294 if(doz!=0) {img2->sizez=2.0*img1->sizez; img2->gapz=2.0*img1->gapz;}
295 img2->sizey=2.0*img1->sizey; img2->gapy=2.0*img1->gapy;
296 img2->sizex=2.0*img1->sizex; img2->gapx=2.0*img1->gapx;
297 }
298
299 /* Calculate the averages of 2x2x2 or 2x2 pixel areas */
300 if(doz!=0) {
301 int fi, pi, yi, xi, pc, yc, xc;
302 for(fi=0; fi<img2->dimt; fi++){
303 for(pi=0, pc=1; pi<img2->dimz; pi++) {
304 for(yi=0, yc=1; yi<img2->dimy; yi++) for(xi=0, xc=1; xi<img2->dimx; xi++) {
305 img2->m[pi][yi][xi][fi]=0.0;
306 if(2*pi+1==img1->dimz) pc=0;
307 if(2*yi+1==img1->dimy) yc=0;
308 if(2*xi+1==img1->dimx) xc=0;
309 img2->m[pi][yi][xi][fi]+=img1->m[2*pi][2*yi][2*xi][fi];
310 img2->m[pi][yi][xi][fi]+=img1->m[2*pi][2*yi][2*xi+xc][fi];
311 img2->m[pi][yi][xi][fi]+=img1->m[2*pi][2*yi+yc][2*xi][fi];
312 img2->m[pi][yi][xi][fi]+=img1->m[2*pi][2*yi+yc][2*xi+xc][fi];
313 img2->m[pi][yi][xi][fi]+=img1->m[2*pi+pc][2*yi][2*xi][fi];
314 img2->m[pi][yi][xi][fi]+=img1->m[2*pi+pc][2*yi][2*xi+xc][fi];
315 img2->m[pi][yi][xi][fi]+=img1->m[2*pi+pc][2*yi+yc][2*xi][fi];
316 img2->m[pi][yi][xi][fi]+=img1->m[2*pi+pc][2*yi+yc][2*xi+xc][fi];
317 img2->m[pi][yi][xi][fi]/=8.0;
318 } /* next row and column */
319 } /* next plane */
320 } /*next frame */
321 } else {
322 int fi, pi, yi, xi, yc, xc;
323 for(fi=0; fi<img2->dimt; fi++){
324 for(pi=0; pi<img2->dimz; pi++) {
325 for(yi=0, yc=1; yi<img2->dimy; yi++) for(xi=0, xc=1; xi<img2->dimx; xi++) {
326 img2->m[pi][yi][xi][fi]=0.0;
327 if(2*yi+1==img1->dimy) yc=0;
328 if(2*xi+1==img1->dimx) xc=0;
329 img2->m[pi][yi][xi][fi]+=img1->m[pi][2*yi][2*xi][fi];
330 img2->m[pi][yi][xi][fi]+=img1->m[pi][2*yi][2*xi+xc][fi];
331 img2->m[pi][yi][xi][fi]+=img1->m[pi][2*yi+yc][2*xi][fi];
332 img2->m[pi][yi][xi][fi]+=img1->m[pi][2*yi+yc][2*xi+xc][fi];
333 img2->m[pi][yi][xi][fi]/=4.0;
334 } /* next row and column */
335 } /* next plane */
336 } /*next frame */
337 }
338
339 return(0);
340}
int imgAllocateWithHeader(IMG *image, int planes, int rows, int columns, int frames, IMG *image_from)
Definition img.c:279

◆ imgSwell()

int imgSwell ( IMG * img1,
IMG * img2,
int doz )

Inflate the image data matrix into twice the original size in each dimension.

Each pixel is inflated into eight pixels, without any interpolation etc.

See also
imgShrink, img2cube, imgScale
Returns
Returns 0 if ok.
Parameters
img1Pointer to the original image; not changed.
img2Pointer to the swollen image; must be initiated. If allocated for correct size, then only pixel values are set; if not, then any previous contents are deleted, memory is allocated, header information is set, and of course the pixel values are set.
dozInflate (1) the image in z dimension (over image planes), or only in x,y dimensions (0).

Definition at line 202 of file imgtransform.c.

212 {
213 if(img1==NULL || img2==NULL) return(1);
214 if(img1->dimz<1 || img1->dimy<1 || img1->dimx<1 || img1->dimt<1) return(2);
215
216 /* Set correct dimensions for the swollen image */
217 int dimz, dimy, dimx;
218 if(doz!=0) dimz=2*img1->dimz; else dimz=img1->dimz;
219 dimy=2*img1->dimy;
220 dimx=2*img1->dimx;
221
222 /* If output image does not yet have these dimensions, then re-allocate it and set headers */
223 if(img2->dimz!=dimz || img2->dimy!=dimy || img2->dimx!=dimx || img2->dimt!=img1->dimt) {
224 /* Allocate memory for the image */
225 int ret=imgAllocateWithHeader(img2, dimz, dimy, dimx, img1->dimt, img1);
226 if(ret) return(10+ret);
227 /* Correct the pixel sizes so that the actual size (cm x cm) of the image won't change */
228 if(doz!=0) {img2->sizez=0.5*img1->sizez; img2->gapz=0.5*img1->gapz;}
229 img2->sizey=0.5*img1->sizey; img2->gapy=0.5*img1->gapy;
230 img2->sizex=0.5*img1->sizex; img2->gapx=0.5*img1->gapx;
231 }
232
233 /* Fill the output image matrix */
234 if(doz!=0) {
235 int x, y, z;
236 for(z=0; z<img1->dimz; z++) for(y=0; y<img1->dimy; y++) for(x=0; x<img1->dimx; x++) {
237 int nz, ny, nx;
238 for(nz=2*z; nz<2+2*z; nz++) for(ny=2*y; ny<2+2*y; ny++) for(nx=2*x; nx<2+2*x; nx++) {
239 for(int t=0; t<img1->dimt; t++) img2->m[nz][ny][nx][t]=img1->m[z][y][x][t];
240 }
241 }
242 } else {
243 int x, y, z;
244 for(z=0; z<img1->dimz; z++) for(y=0; y<img1->dimy; y++) for(x=0; x<img1->dimx; x++) {
245 int ny, nx;
246 for(ny=2*y; ny<2+2*y; ny++) for(nx=2*x; nx<2+2*x; nx++) {
247 for(int t=0; t<img1->dimt; t++) img2->m[z][ny][nx][t]=img1->m[z][y][x][t];
248 }
249 }
250 }
251
252 return(0);
253}

◆ integerScale()

void integerScale ( int frame,
float *** src,
float ** targ,
int width,
int height,
int zoom )

Magnify one frame of dynamic 2D image by integer zoom factor. Pixel values are simply duplicated.

See also
imgScale
Parameters
frameIndex of the frame to be scaled.
srcSource data in dynamic 2D array: srcp[y][x][frame].
targPre-allocated target static 2D data matrix: targ[y][x]; actual matrix size is allowed to be larger than what is used here.
widthWidth (x dim) of the source data matrix.
heightHeight (y dim) of the source data matrix.
zoomZoom factor. If less than 2, then matrix is just copied.

Definition at line 159 of file imgtransform.c.

173 {
174 if(frame<0) frame=0;
175 if(zoom<1) zoom=1;
176
177 int w, h, z;
178
179 for(h=0; h<height; h++){
180 for(w=0; w<width; w++){
181 float val=src[h][w][frame];
182 for(z=0; z<zoom; z++) {
183 targ[h*zoom][w*zoom + z]=val;
184 }
185 }
186 /* Copy to next rows */
187 for(z=1; z<zoom; z++) {
188 for(int i=0; i<zoom*width; i++) targ[h*zoom+z][i]=targ[h*zoom+z-1][i];
189 //memcpy(targ[h*zoom+z], targ[h*zoom], width*zoom*sizeof(float));
190 }
191 }
192}

Referenced by imgScale().