| Bsoft 2.0.5 Bernard's software package

Bimage_bin.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "utilities.h"
11
12 // Declaration of global variables
13 extern int verbose; // Level of output to the screen
14
15
16 int Bimage::integer_interpolation(int integer_factor)
17 {
18 return integer_interpolation(integer_factor, 21);
19 }
20
50 int Bimage::integer_interpolation(int integer_factor, int odd)
51 {
52 if ( integer_factor < 2 ) return 0;
53
54 // Calculate the new size and kernel weights
55 long i, j, ix, iy, iz, cc;
56 long nn, wx, wy, wz, xx, yy, zz;
57 int dimensions(0);
58 Vector3<long> nusize(1,1,1);
59 Vector3<long> oldnomori(x/2, y/2, z/2);
60 Vector3<long> nunomori;
61 Vector3<long> kernelsize(1,1,1);
62 Vector3<double> nusam(image->sampling());
63
64 if ( x > 1 ) {
65 kernelsize[0] = 2*integer_factor - 1;
66 nusize[0] = (x + 1)/integer_factor;
67 if ( (odd & 1) && nusize[0]%2 == 0 ) nusize[0]--; // Size must be odd
68 if ( (odd & 2) && nusize[0]%2 == 1 ) nusize[0]--; // Size must be even
69 nunomori[0] = nusize[0]/2;
70 nusam[0] *= integer_factor;
71 dimensions++;
72 }
73 if ( y > 1 ) {
74 kernelsize[1] = 2*integer_factor - 1;
75 nusize[1] = (y + 1)/integer_factor;
76 if ( (odd & 4) && nusize[1]%2 == 0 ) nusize[1]--; // Size must be odd
77 if ( (odd & 8) && nusize[1]%2 == 1 ) nusize[1]--; // Size must be even
78 nunomori[1] = nusize[1]/2;
79 nusam[1] *= integer_factor;
80 dimensions++;
81 }
82 if ( z > 1 ) {
83 kernelsize[2] = 2*integer_factor - 1;
84 nusize[2] = (z + 1)/integer_factor;
85 if ( (odd & 16) && nusize[2]%2 == 0 ) nusize[2]--; // Size must be odd
86 if ( (odd & 32) && nusize[2]%2 == 1 ) nusize[2]--; // Size must be even
87 nunomori[2] = nusize[2]/2;
88 nusam[2] *= integer_factor;
89 dimensions++;
90 }
91
92 double kernel_scale = 1.0/pow(1.0*integer_factor, 2.0*dimensions);
93 vector<double> kernel(kernelsize[0]*kernelsize[1]*kernelsize[2]);
94
95 for ( i=zz=0; zz<kernelsize[2]; zz++ ) {
96 wz = (int) (integer_factor - fabs(integer_factor - 1.0 - zz));
97 for ( yy=0; yy<kernelsize[1]; yy++ ) {
98 wy = (int) (integer_factor - fabs(integer_factor - 1.0 - yy));
99 for ( xx=0; xx<kernelsize[0]; xx++, i++ ) {
100 wx = (int) (integer_factor - fabs(integer_factor - 1.0 - xx));
101 kernel[i] = wx*wy*wz*kernel_scale;
102 }
103 }
104 }
105
106 long datasize = n*nusize[0]*nusize[1]*nusize[2]*c;
107 double* nudata = new double[datasize];
108
109 if ( verbose & VERB_PROCESS ) {
110 cout << "Special integer interpolation:" << endl;
111 cout << "Integer factor: " << integer_factor << endl;
112 cout << "Interpolation kernel size: " << kernelsize << endl;
113 cout << "New image size: " << nusize << endl;
114 } else if ( verbose & VERB_LABEL )
115 cout << "Special integer interpolation" << endl << endl;
116
117 if ( verbose & VERB_FULL ) {
118 cout << "Kernel interpolation: Kernel" << endl;
119 for ( i=zz=0; zz<kernelsize[2]; zz++ ) {
120 for ( yy=0; yy<kernelsize[1]; yy++ ) {
121 for ( xx=0; xx<kernelsize[0]; xx++, i++ ) {
122 cout << " " << kernel[i];
123 }
124 cout << endl;
125 }
126 }
127 cout << endl;
128 }
129
130 // Do the kernel interpolation
131 long oldx, oldy, oldz, xkernel, ykernel, zkernel;
132 long zlo, zhi, ylo, yhi, xlo, xhi;
133 vector<double> sum(c);
134
135 for ( nn=0; nn<n; nn++ ) {
136 for ( iz=0; iz<nusize[2]; iz++ ) {
137 oldz = (iz - nunomori[2])*integer_factor + oldnomori[2] - kernelsize[2]/2;
138 zlo = oldz;
139 if ( zlo < 0 ) zlo = 0;
140 zhi = oldz + kernelsize[2];
141 if ( zhi > z ) zhi = z;
142 for ( iy=0; iy<nusize[1]; iy++ ) {
143 oldy = (iy - nunomori[1])*integer_factor + oldnomori[1] - kernelsize[1]/2;
144 ylo = oldy;
145 if ( ylo < 0 ) ylo = 0;
146 yhi = oldy + kernelsize[1];
147 if ( yhi > y ) yhi = y;
148 for ( ix=0; ix<nusize[0]; ix++ ) {
149 oldx = (ix - nunomori[0])*integer_factor + oldnomori[0] - kernelsize[0]/2;
150 xlo = oldx;
151 if ( xlo < 0 ) xlo = 0;
152 xhi = oldx + kernelsize[0];
153 if ( xhi > x ) xhi = x;
154 for ( cc=0; cc<c; cc++ ) sum[cc] = 0;
155 for ( zz=zlo; zz<zhi; zz++ ) {
156 zkernel = zz - oldz;
157 for ( yy=ylo; yy<yhi; yy++ ) {
158 ykernel = yy - oldy;
159 for ( xx=xlo; xx<xhi; xx++ ) {
160 xkernel = xx - oldx;
161 i = index(0, xx, yy, zz, nn);
162 j = (zkernel*kernelsize[1] + ykernel)*kernelsize[0] + xkernel;
163 for ( cc=0; cc<c; cc++ ) sum[cc] += (*this)[i++] * kernel[j];
164
165 }
166 }
167 }
168 i = (((nn*nusize[2] + iz)*nusize[1] + iy)*nusize[0] + ix)*c;
169 for ( cc=0; cc<c; cc++ ) nudata[i++] = sum[cc];
170 }
171 }
172 }
173 image[nn].origin((image[nn].origin() - oldnomori)/integer_factor + nunomori);
174 if ( verbose & VERB_STATS )
175 cout << "Image " << nn+1 << " origin: " << image[nn].origin() << endl;
176 }
177
178 if ( verbose & VERB_DEBUG )
179 cout << "Kernel interpolation: Sums done" << endl;
180
181 // Set new image parameters
182 size(nusize);
183 page_size(nusize);
184 sampling(nusam);
185
186 // Transfer the data to a new block and free the old
187 data_alloc();
188 for ( i=0; i<datasize; i++ ) set(i, nudata[i]);
189
190 delete[] nudata;
191
192 statistics();
193
194 return 0;
195 }
196
197 int Bimage::bin(long i, Vector3<long> bk, Bimage* pb)
198 {
199 long j, cc, xx, yy, zz;
200 long nn(i/(pb->image_size()*c));
201 Vector3<long> coor = pb->coordinates(i);
202 Vector3<long> bs(bk * coor);
203 Vector3<long> bf(bs + bk);
204 long binsize(0);
205 vector<double> binsum(c);
206 for ( cc=0; cc<c; cc++ ) binsum[cc] = 0;
207
208 for ( zz=bs[2]; zz<bf[2] && zz<z; zz++ ) {
209 for ( yy=bs[1]; yy<bf[1] && yy<y; yy++ ) {
210 for ( xx=bs[0]; xx<bf[0] && xx<x; xx++ ) {
211 binsize++;
212 j = index(0, xx, yy, zz, nn);
213 for ( cc=0; cc<c; cc++ ) binsum[cc] += (*this)[j++];
214 }
215 }
216 }
217
218 for ( cc=0; cc<c; cc++ ) pb->set(i++, binsum[cc]/binsize);
219
220 return 0;
221 }
222
231 int Bimage::bin(Vector3<long> bk)
232 {
233 if ( verbose & VERB_DEBUG )
234 cout << "DEBUG Bimage::bin: bk=" << bk << endl;
235
236 Bimage* pb = bin_copy(bk);
237
238 // Set new image parameters
239 size(pb->size());
240 page_size(size());
241 sampling(pb->sampling());
242
243 for ( long i=0; i<n; i++ ) image[i].origin(pb->image[i].origin());
244
245 // cout << "alloc_size=" << alloc_size() << endl;
246 // Transfer the data to a new block and free the old
247 data_alloc();
248 // cout << "datasize=" << datasize << endl;
249 for ( long i=0; i<datasize; i++ ) set(i, (*pb)[i]);
250 delete pb;
251
252 statistics();
253
254 return 0;
255 }
256
265 Bimage* Bimage::bin_copy(Vector3<long> bk)
266 {
267 if ( bk[0] < 1 ) bk[0] = 1;
268 if ( bk[1] < 1 ) bk[1] = 1;
269 if ( bk[2] < 1 ) bk[2] = 1;
270 if ( x < bk[0] ) bk[0] = x;
271 if ( y < bk[1] ) bk[1] = y;
272 if ( z < bk[2] ) bk[2] = z;
273
274 if ( bk[0]*bk[1]*bk[2] < 2 ) return copy();
275
276 Vector3<long> nusize;
277 nusize[0] = (x + bk[0] - 1)/bk[0];
278 nusize[1] = (y + bk[1] - 1)/bk[1];
279 nusize[2] = (z + bk[2] - 1)/bk[2];
280
281 Bimage* pb = copy_header();
282
283 pb->data_type(Float);
284 pb->size(nusize);
285 pb->sampling(image->sampling()*bk);
286
287 for ( long i=0; i<pb->images(); i++ ) pb->image[i].origin(pb->image[i].origin()/bk);
288
289 pb->data_alloc();
290
291 if ( verbose & VERB_PROCESS ) {
292 cout << "Binning:" << endl;
293 cout << "Bin size: " << bk << endl;
294 cout << "New image size: " << nusize << endl << endl;
295 } else if ( verbose & VERB_LABEL )
296 cout << "Binning" << endl << endl;
297
298 #ifdef HAVE_GCD
299 dispatch_apply(pb->data_size()/c, dispatch_get_global_queue(0, 0), ^(size_t i){
300 bin(i*c, bk, pb);
301 });
302 #else
303 #pragma omp parallel for
304 for ( long i=0; i<pb->data_size(); i+=c )
305 bin(i, bk, pb);
306 #endif
307
308 if ( verbose & VERB_DEBUG )
309 cout << "Binning: Sums done" << endl;
310
311 pb->statistics();
312
313 // pb->information();
314 // delete pb;
315
316 return pb;
317 }
318
327 Bimage* Bimage::bin_around_origin(int bin)
328 {
329 if ( bin%2 == 0 ) bin++; // bin must be odd
330
331 Bimage* pt = copy();
332
333 pt->filter_average(bin);
334
335 long i, j, xx, yy, zz, xo, yo, zo, xj, yj, zj, nn;
336 Vector3<long> nusize(x/bin + 1, y/bin + 1, z/bin + 1);
337 Vector3<double> shift;
338
339 if ( verbose & VERB_PROCESS ) {
340 cout << "Binning: " << bin << endl;
341 cout << "New binned size: " << nusize << endl << endl;
342 }
343
344 Bimage* pb = new Bimage(Float, compoundtype, nusize, n);
345 pb->sampling(image->sampling()*bin);
346
347 for ( i=nn=0; nn<n; ++nn ) {
348 pb->image[nn].origin(image[nn].origin()/bin);
349 shift = image[nn].origin() - pb->image[nn].origin() * bin;
350 if ( verbose )
351 cout << nn << tab << shift << endl;
352 zo = shift[2];
353 for ( zz=0; zz<pb->sizeZ(); ++zz, zo+=bin ) {
354 zj = zo;
355 if ( zj < 0 ) zj = 0;
356 if ( zj >= z ) zj = z - 1;
357 yo = shift[1];
358 for ( yy=0; yy<pb->sizeY(); ++yy, yo+=bin ) {
359 yj = yo;
360 if ( yj < 0 ) yj = 0;
361 if ( yj >= y ) yj = y - 1;
362 xo = shift[0];
363 for ( xx=0; xx<pb->sizeX(); ++xx, xo+=bin, ++i ) {
364 xj = xo;
365 if ( xj < 0 ) xj = 0;
366 if ( xj >= x ) xj = x - 1;
367 j = index(0, xj, yj, zj, nn);
368 pb->set(i, (*pt)[j]);
369 }
370 }
371 }
372 }
373
374 delete pt;
375
376 return pb;
377 }
378
379
388 int Bimage::median_bin(int binning)
389 {
390 if ( binning < 2 ) return -1;
391
392 if ( compound_type() > TSimple ) {
393 error_show("Bimage::median_bin", __FILE__, __LINE__);
394 cerr << "Error: Interpolation of compound data sets not supported!" << endl << endl;
395 return -1;
396 }
397
398 // Calculate the new size and set up
399 long i, j, k;
400 long nn, ix, iy, iz, xx, yy, zz, dimensions(0);
401 Vector3<long> nusize(1,1,1);
402 Vector3<long> shift;
403 Vector3<long> blocksize(1,1,1);
404 Vector3<double> nusam(image->sampling());
405
406 if ( x > 1 ) {
407 blocksize[0] = 2*binning - 1;
408 nusize[0] = (x + 1)/binning;
409 if ( 2*(nusize[0]/2) == nusize[0] ) nusize[0]--; // Size must be odd
410 shift[0] = nusize[0] - x/binning;
411 nusam[0] *= binning;
412 dimensions++;
413 }
414 if ( y > 1 ) {
415 blocksize[1] = 2*binning - 1;
416 nusize[1] = (y + 1)/binning;
417 if ( 2*(nusize[1]/2) == nusize[1] ) nusize[1]--; // Size must be odd
418 shift[1] = nusize[1] - y/binning;
419 nusam[1] *= binning;
420 dimensions++;
421 }
422 if ( z > 1 ) {
423 blocksize[2] = 2*binning - 1;
424 nusize[2] = (z + 1)/binning;
425 if ( 2*(nusize[2]/2) == nusize[2] ) nusize[2]--; // Size must be odd
426 shift[2] = nusize[2] - z/binning;
427 nusam[2] *= binning;
428 dimensions++;
429 }
430
431 long blocktotalsize = blocksize[0]*blocksize[1]*blocksize[2];
432 vector<double> block(blocktotalsize);
433
434 long datasize = n*nusize[0]*nusize[1]*nusize[2]*c;
435 double* nudata = new double[datasize];
436
437 if ( verbose & VERB_PROCESS ) {
438 cout << "Binning using a median filter:" << endl;
439 cout << "Block size: " << blocksize << endl;
440 cout << "New image size: " << nusize << endl << endl;
441 } else if ( verbose & VERB_LABEL )
442 cout << "Binning using a median filter" << endl << endl;
443
444 // Do the median binning interpolation
445 long oldx, oldy, oldz, xblock, yblock, zblock, nblock, imedian;
446 long zlo, zhi, ylo, yhi, xlo, xhi;
447 for ( i=nn=0; nn<n; nn++ ) {
448 for ( iz=0; iz<nusize[2]; iz++ ) {
449 oldz = iz*binning - shift[2]; // Origin of the block
450 zlo = oldz;
451 if ( zlo < 0 ) zlo = 0;
452 zhi = oldz + blocksize[2];
453 if ( zhi > z ) zhi = z;
454 for ( iy=0; iy<nusize[1]; iy++ ) {
455 oldy = iy*binning - shift[1];
456 ylo = oldy;
457 if ( ylo < 0 ) ylo = 0;
458 yhi = oldy + blocksize[1];
459 if ( yhi > y ) yhi = y;
460 for ( ix=0; ix<nusize[0]; ix++, i++ ) {
461 oldx = ix*binning - shift[0];
462 xlo = oldx;
463 if ( xlo < 0 ) xlo = 0;
464 xhi = oldx + blocksize[0];
465 if ( xhi > x ) xhi = x;
466 nblock = 0;
467 for ( zz=zlo; zz<zhi; zz++ ) {
468 zblock = zz - oldz;
469 for ( yy=ylo; yy<yhi; yy++ ) {
470 yblock = yy - oldy;
471 for ( xx=xlo; xx<xhi; xx++ ) {
472 xblock = xx - oldx;
473 k = ((nn*z + zz)*y + yy)*x + xx;
474 j = (zblock*blocksize[1] + yblock)*blocksize[0] + xblock;
475 block[j] = (*this)[k];
476 nblock++;
477 }
478 }
479 }
480 imedian = nblock/2;
481 partition(block, nblock, imedian);
482 nudata[i] = block[imedian];
483 }
484 }
485 }
486 image[nn].origin(image[nn].origin() * (1.0/binning));
487 if ( verbose & VERB_STATS )
488 cout << "Image " << nn+1 << " origin: " << image[nn].origin() << endl;
489 }
490
491 if ( verbose & VERB_DEBUG )
492 cout << "Median binning interpolation done" << endl;
493
494 // Set new image parameters
495 size(nusize);
496 page_size(nusize);
497 sampling(nusam);
498
499 // Transfer the data to a new block and free the old
500 data_alloc();
501 for ( i=0; i<datasize; i++ ) set(i, nudata[i]);
502
503 delete[] nudata;
504
505 statistics();
506
507 return 0;
508 }
509
VERB_STATS
#define VERB_STATS
Definition: utilities.h:108
Bimage::copy_header
Bimage * copy_header()
Definition: Bimage.h:650
Bimage.h
Header file for image class.
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Bimage::image_size
long image_size()
Definition: Bimage.h:267
utilities.h
Header file for general utilities.
Bimage::bin_copy
Bimage * bin_copy(long b)
Definition: Bimage.h:1284
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
Bimage::median_bin
int median_bin(int binning)
Bins by an integer size, selecting the kernel median.
Definition: Bimage_bin.cpp:388
Bimage::index
long index(long nx, long ny) const
Definition: Bimage.h:383
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
Bimage::Bimage
Bimage()
Initializes an image.
Definition: Bimage.cpp:44
TSimple
Definition: Bimage.h:58
Float
Definition: utilities.h:157
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:256
Bimage::shift
int shift(Vector3< double > vec, int fill_type=0, double fill=0)
Shifts an image.
Definition: Bimage_transform.cpp:587
Bimage::filter_average
int filter_average(long kernel_size)
Applies an averaging filter to an image.
Definition: Bimage_filter.cpp:208
Bimage::statistics
long statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Bimage::sum
void sum(long m, Bimage **p)
Sums an array of images with their FOM blocks.
Definition: Bimage_combine.cpp:23
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bsub_image::sampling
void sampling(double x, double y, double z)
Definition: Bimage.h:123
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2695
Bimage::sizeX
void sizeX(long nx)
Definition: Bimage.h:377
Bimage::sizeZ
void sizeZ(long nz)
Definition: Bimage.h:379
Vector3< long >
verbose
int verbose
Bimage::integer_interpolation
int integer_interpolation(int integer_factor)
Definition: Bimage_bin.cpp:16
partition
int partition(vector< double > &a, int n, int k)
Determines the index k'th value in the array.
Definition: math_util.cpp:123
Bimage::bin_around_origin
Bimage * bin_around_origin(int bin)
Bins by an integer size making sure the origin falls on a binned voxel, and returns a new image.
Definition: Bimage_bin.cpp:327
kernel
Definition: kernlut.h:13
Bimage::page_size
Vector3< long > page_size()
Definition: Bimage.h:480
Bimage::images
long images()
Definition: Bimage.h:491
Bimage::coordinates
void coordinates(long i, long &nx, long &ny, long &nz)
Definition: Bimage.h:416
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::sizeY
void sizeY(long ny)
Definition: Bimage.h:378
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:106
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
Bimage::data_size
long data_size()
Definition: Bimage.h:255
error_show
int error_show(string message, string file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:755
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563