TPCCLIB
Loading...
Searching...
No Matches
imgtransform.c
Go to the documentation of this file.
1
5/*****************************************************************************/
6#include "libtpcimgp.h"
7/*****************************************************************************/
8
9/*****************************************************************************/
18 IMG *img1,
20 int dim,
22 IMG *img2
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}
117/*****************************************************************************/
118
119/*****************************************************************************/
125 IMG *src,
127 IMG *targ,
129 float zoom,
131 int method
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}
152/*****************************************************************************/
153
154/*****************************************************************************/
161 int frame,
163 float ***src,
166 float **targ,
168 int width,
170 int height,
172 int zoom
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}
193/*****************************************************************************/
194
195/*****************************************************************************/
204 IMG *img1,
209 IMG *img2,
211 int doz
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}
254/*****************************************************************************/
255
256/*****************************************************************************/
265 IMG *img1,
270 IMG *img2,
273 int doz
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}
341/*****************************************************************************/
342
343/*****************************************************************************/
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
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
int img2cube(IMG *img1, int dim, IMG *img2)
void integerScale(int frame, float ***src, float **targ, int width, int height, int zoom)
void imgScale(IMG *src, IMG *targ, float zoom, int method)
int imgShrink(IMG *img1, IMG *img2, int doz)
int imgSwell(IMG *img1, IMG *img2, int doz)
#define IMG_STATUS_OCCUPIED
Header file for libtpcimgp.
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