| Bsoft 2.0.5 Bernard's software package

Bimage.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "utilities.h"
11
12 #include <iostream>
13 using namespace std;
14
15 // Definition of the global variables
16 extern int verbose; // Level of output to the screen
17
24 Bsub_image::Bsub_image()
25 {
26 min = max = avg = std = 0;
27 bkg = 0;
28 ux = uy = uz = 1;
29 ox = oy = oz = 0;
30 vx = vy = vz = angle = 0;
31 mag = 1;
32 fom = 1;
33 sel = 1;
34 // cout << "sub-image initialized" << endl;
35 }
36
37
44 Bimage::Bimage()
45 {
46 if ( verbose & VERB_DEBUG )
47 cout << "DEBUG Bimage: Bimage size = " << sizeof(Bimage) << endl;
48
49 initialize();
50 }
51
58 Bimage::Bimage(const Bimage& p)
59 {
60 // cout << "Copy image" << endl;
61 internal_copy(p);
62 }
63
70 Bimage::Bimage(Bstring& fn, int readdata, int img_select)
71 {
72 if ( verbose & VERB_DEBUG )
73 cout << "DEBUG Bimage: Bimage size = " << sizeof(Bimage) << endl;
74
75 initialize();
76
77 }
78
92 Bimage::Bimage(DataType type, CompoundType ctype, long nx, long ny,
93 long nz, long nn)
94 {
95 initialize(ctype, nx, ny, nz, nn);
96
97 data_type(type);
98
99 data_alloc();
100 }
101
113 Bimage::Bimage(DataType type, CompoundType ctype, Vector3<long> size, long nn)
114 {
115 initialize(ctype, size[0], size[1], size[2], nn);
116
117 data_type(type);
118
119 data_alloc();
120 }
121
133 Bimage::Bimage(DataType type, CompoundType ctype, vector<long> size, long nn)
134 {
135 initialize(ctype, size[0], size[1], size[2], nn);
136
137 data_type(type);
138
139 data_alloc();
140 }
141
155 Bimage::Bimage(DataType type, long nc, long nx, long ny,
156 long nz, long nn)
157 {
158 initialize(nc, nx, ny, nz, nn);
159
160 data_type(type);
161
162 data_alloc();
163 }
164
176 Bimage::Bimage(DataType type, long nc, Vector3<long> size, long nn)
177 {
178 initialize(nc, size[0], size[1], size[2], nn);
179
180 data_type(type);
181
182 data_alloc();
183 }
184
191 Bimage::~Bimage()
192 {
193 if ( next ) {
194 try { delete next; }
195 catch (...) { cerr << "Failed to deallocate next image!" << endl; }
196 }
197 next = NULL;
198
199 // Strings
200 id = 0;
201
202 // metadata.erase();
203
204 if ( image ) {
205 try { delete[] image; }
206 catch (...) { cerr << "Failed to deallocate sub-images!" << endl; }
207 }
208 image = NULL;
209
210 if ( d.uc ) {
211 try { delete[] d.uc; }
212 catch (...) { cerr << "Failed to deallocate data block!" << endl; }
213 }
214 d.uc = NULL;
215 }
216
217 /*
218 @brief Image initialization function.
219
220 All properties are set to default values.
221
222 **/
223 void Bimage::initialize()
224 {
225 // Set parameter defaults
226 x = y = z = c = n = 0;
227 px = py = pz = 0;
228 sn = sz = 0;
229 ss = 1;
230
231 data_type(UCharacter);
232 compoundtype = TSimple;
233 fouriertype = NoTransform;
234
235 offset = 0;
236
237 min = max = avg = std = 0;
238 smin = smax = 0;
239
240 ucell = UnitCell();
241
242 // Strings
243 id = 0;
244
245 // Metadata
246 metadata = JSvalue(JSobject);
247 // metadata["version"] = BVERSION; // Version number
248 // metadata["time"] = time(NULL);
249 // cout << "metadata type = " << metadata.type() << endl;
250 // cout << metadata << endl;
251 next = NULL;
252 image = NULL;
253 d.uc = NULL;
254
255 data_size();
256
257 if ( verbose & VERB_DEBUG )
258 cout << "DEBUG Bimage::initialize: Image setup done" << endl;
259 }
260
261 void Bimage::initialize(long nc, long nx,
262 long ny, long nz, long nn)
263 {
264 initialize();
265
266 c = nc;
267 x = nx;
268 y = ny;
269 z = nz;
270
271 if ( c > 1 ) compoundtype = TMulti;
272
273 images(nn);
274 }
275
276 void Bimage::initialize(CompoundType ctype, long nx,
277 long ny, long nz, long nn)
278 {
279 long nc;
280
281 switch ( ctype ) {
282 case TSimple: nc = 1; break;
283 case TComplex: nc = 2; break;
284 case TVector3: nc = 3; break;
285 case TView: nc = 4; break;
286 case TRGB: nc = 3; break;
287 case TRGBA: nc = 4; break;
288 case TCMYK: nc = 4; break;
289 default: nc = 1;
290 }
291
292 initialize(nc, nx, ny, nz, nn);
293
294 compoundtype = ctype;
295 }
296
297 void Bimage::images(long nn) {
298 if ( nn <= 0 )
299 cerr << "Error in Bimage::images: The number of images must be greater than 1" << endl;
300 if ( nn == n ) return;
301 if ( nn != n && image ) { delete[] image; image = NULL; }
302 if ( !image ) image = new Bsub_image[nn];
303 n = nn;
304 }
305
306 /*
307 void Bimage::images(long nn) {
308 if ( nn <= 0 )
309 cerr << "Error in Bimage::images: The number of images must be greater than 1" << endl;
310 if ( nn == n ) return;
311 JSvalue arr(JSarray);
312 JSvalue img(JSobject);
313 vector<double> sam{1,1,1}, ori{double(x/2),double(y/2),double(z/2)};
314 if ( metadata.exists("image") )
315 arr = metadata["image"].array();
316 if ( nn > n ) {
317 for ( long i=n+1; i<=nn; ++i ) {
318 img["number"] = i;
319 img["sampling"] = sam;
320 img["origin"] = ori;
321 img["magnification"] = 1.0;
322 img["background"] = 0.0;
323 img["fom"] = 0.0;
324 img["select"] = 1;
325 arr.push_back(img);
326 }
327 metadata["image"] = arr;
328 } else {
329 arr.erase(arr.begin()+nn, arr.end());
330 }
331 if ( nn != n && image ) { delete[] image; image = NULL; }
332 if ( !image ) image = new Bsub_image[nn];
333 n = nn;
334 }
335 */
336 void Bimage::internal_copy(const Bimage& p)
337 {
338 offset = p.offset;
339
340 data_type(p.datatype);
341 compoundtype = p.compoundtype;
342 fouriertype = p.fouriertype;
343 c = p.c;
344 x = p.x;
345 y = p.y;
346 z = p.z;
347 // n = p.n;
348 px = p.px;
349 py = p.py;
350 pz = p.pz;
351
352 min = p.min;
353 max = p.max;
354 avg = p.avg;
355 std = p.std;
356
357 ucell = p.ucell;
358
359 // Strings
360 id = p.id;
361
362 next = NULL;
363
364 images(p.n);
365 // cout << "image pointer:" << image << "." << endl;
366 if ( p.image )
367 for ( long j=0; j<n; j++ ) image[j] = p.image[j];
368
369 // Metadata
370 metadata = p.metadata;
371
372 data_size();
373 long allocsize = alloc_size();
374
375 if ( d.uc ) delete[] d.uc;
376 d.uc = NULL;
377 if ( p.d.uc ) {
378 d.uc = new unsigned char[allocsize];
379 for ( long j=0; j<datasize; j++ ) set(j, p[j]);
380 }
381 // cout << "data pointer:" << &d.uc << "." << endl;
382
383 }
384
389 void Bimage::check()
390 {
391 long j;
392
393 check_sampling();
394
395 Vector3<double> u(image->sampling());
396
397 if ( fouriertype > Standard ) fouriertype = Standard;
398
399 if ( c < 1 ) c = 1;
400 if ( px < 1 ) px = x;
401 if ( py < 1 ) py = y;
402 if ( pz < 1 ) pz = z;
403 if ( px > 2*x ) px = x;
404 if ( py > 2*y ) py = y;
405 if ( pz > 2*z ) pz = z;
406 if ( n < 1 ) n = 1;
407 // if ( ux <= 1e-6 ) ux = 1;
408 // if ( uy <= 1e-6 ) uy = 1;
409 // if ( uz <= 1e-6 ) uz = 1;
410 // if ( ux > 1e6 ) ux = 1;
411 // if ( uy > 1e6 ) uy = 1;
412 // if ( uz > 1e6 ) uz = 1;
413 // if ( fabs(ux - uy) > 100 ) ux = uy = uz = 1;
414 if ( !compoundtype ) compoundtype = TSimple;
415
416 switch ( compoundtype ) {
417 case TSimple: j = 1;
418 case TComplex: j = 2;
419 case TVector3: j = 3;
420 case TView: j = 4;
421 case TRGB: j = 3;
422 case TRGBA: j = 4;
423 case TCMYK: j = 4;
424 default: j = c;
425 }
426
427 if ( j != c ) {
428 cerr << "Error in Bimage::check: The compound type size (" << j << ") and number of channels (" << c << ") don't agree!" << endl;
429 bexit(-1);
430 }
431
432 data_size();
433
434 if ( verbose & VERB_DEBUG ) {
435 cout << "DEBUG Bimage::check: Data type=" << datatype << " Compound type=" << compoundtype << endl;
436 cout << "DEBUG Bimage::check: Images & channels: " << n << " " << c << endl;
437 cout << "DEBUG Bimage::check: Size: " << x << " " << y << " " << z << endl;
438 cout << "DEBUG Bimage::check: Page: " << px << " " << py << " " << pz << endl;
439 cout << "DEBUG Bimage::check: Units: " << u[0] << " " << u[1] << " " << u[2] << endl;
440 cout << "DEBUG Bimage::check: min=" << min << " max=" << max << " avg=" << avg << " std=" << std << endl;
441 }
442
443 if ( !image ) {
444 cerr << "Error in Bimage::check: The sub-image list has not been allocated!" << endl;
445 bexit(-1);
446 }
447
448 int check_stats = 0;
449
450 if ( !isfinite(min) || !isfinite(max) || !isfinite(avg) || !isfinite(std) ) check_stats = 1;
451
452 if ( (min>=max) || (std<=0) || (avg<min) || (avg>max) ) check_stats = 1;
453
454 if ( min < dtmin ) check_stats = 1;
455 if ( max > dtmax ) check_stats = 1;
456
457 if ( check_stats ) statistics();
458
459 if ( smin == 0 && smax == 0 ) {
460 smin = min;
461 smax = max;
462 }
463
464 if ( verbose & VERB_DEBUG ) {
465 cout << "DEBUG Bimage::check: Min, max, mean, stdev: " <<
466 min << " " << max << " " << avg << " " << std << endl;
467 cout << "DEBUG Bimage::check: Background:";
468 // for ( j=0; j<n; j++ ) cout << " " << image[j].background();
469 // cout << endl;
470 for ( j=0; j<n; j++ ) cout << " " << background(j);
471 cout << endl;
472 }
473
474 View view;
475 for ( j=0; j<n; j++ ) {
476 if ( !isfinite(image[j].background()) ) image[j].background(0);
477 else if ( fabs((double)image[j].background()) < 1e-30 ) image[j].background(0);
478 if ( !isfinite(image[j].origin()[0]) || !isfinite(image[j].origin()[0])
479 | !isfinite(image[j].origin()[0]) ) image[j].origin(0,0,0);
480 view = image[j].view();
481 view.normalize();
482 image[j].view(view);
483 if ( image[j].magnification() <= 0 )
484 image[j].magnification(1);
485 }
486
487 UnitCell uc = unit_cell();
488
489 if ( verbose & VERB_DEBUG )
490 cout << "DEBUG Bimage::check: Unit cell: " << uc.a() << " " << uc.b() << " " << uc.c()
491 << " " << uc.alpha() << " " << uc.beta() << " " << uc.gamma() << endl;
492
493
494 if ( uc.a() < 1 ) uc.a(u[0]*x);
495 if ( uc.b() < 1 ) uc.b(u[1]*y);
496 if ( uc.c() < 1 ) uc.c(u[2]*z);
497 if ( uc.a() > 100*x*u[0] ) uc.a(u[0]*x);
498 if ( uc.b() > 100*y*u[1] ) uc.b(u[1]*y);
499 if ( uc.c() > 100*z*u[2] ) uc.c(u[2]*z);
500 if ( uc.alpha() > TWOPI || uc.beta() > TWOPI || uc.gamma() > TWOPI ) uc.degrees_to_radians();
501 if ( uc.alpha() < 0.001 || uc.alpha() > M_PI ) uc.alpha(M_PI_2);
502 if ( uc.beta() < 0.001 || uc.beta() > M_PI ) uc.beta(M_PI_2);
503 if ( uc.gamma() < 0.001 || uc.gamma() > M_PI ) uc.gamma(M_PI_2);
504
505 unit_cell(uc);
506
507 if ( verbose & VERB_DEBUG )
508 cout << "DEBUG Bimage::check: Unit cell: " << uc.a() << " " << uc.b() << " " << uc.c()
509 << " " << uc.alpha() << " " << uc.beta() << " " << uc.gamma() << endl;
510 /*
511 Bstring t;
512 if ( lbl.length() ) {
513 j = lbl.length() - 1;
514 if ( verbose & VERB_DEBUG )
515 cout << "DEBUG Bimage::check: lbl length=" << j << " last=" << lbl[j] << endl;
516 // if ( verbose & VERB_DEBUG )
517 // cout << "DEBUG Bimage::check: lbl=" << lbl << "/end/" << endl;
518 while ( j > 0 && isspace(lbl[j]) ) j--;
519 j++;
520 if ( j < lbl.length() ) lbl = lbl.left(j);
521 }
522 */
523 if ( verbose & VERB_DEBUG )
524 cout << "DEBUG Bimage::check: Finished checking parameters" << endl;
525 }
526
536 bool Bimage::check_if_same_size(Bimage* p)
537 {
538 if ( !p ) {
539 error_show("Both images must be defined", __FILE__, __LINE__);
540 return 0;
541 }
542
543 if ( x != p->x || y != p->y || z != p->z || c != p->c || n != p->n ) {
544 cerr << "Error: Image dimensions not the same:" << endl;
545 cerr << "Image 1: c=" << c << " x=" << x << " y=" << y << " z=" << z << " n=" << n << endl;
546 cerr << "Image 2: c=" << p->c << " x=" << p->x << " y=" << p->y << " z=" << p->z << " n=" << p->n << endl;
547 return 0;
548 }
549
550 return 1;
551 }
552
562 bool Bimage::check_if_same_image_size(Bimage* p)
563 {
564 if ( !p ) {
565 error_show("Both images must be defined", __FILE__, __LINE__);
566 return 0;
567 }
568
569 if ( x != p->x || y != p->y || z != p->z || c != p->c ) {
570 cerr << "Error: Image dimensions not the same:" << endl;
571 cerr << "Image 1: c=" << c << " x=" << x << " y=" << y << " z=" << z << " n=" << n << endl;
572 cerr << "Image 2: c=" << p->c << " x=" << p->x << " y=" << p->y << " z=" << p->z << " n=" << p->n << endl;
573 return 0;
574 }
575
576 return 1;
577 }
578
586 void Bimage::check_sampling()
587 {
588 Vector3<double> u(image->sampling());
589
590 for ( long i=0; i<3; ++i ) {
591 if ( u[i] <= 1e-10 ) u[i] = 1;
592 if ( size()[i] < 2 ) u[i] = 1;
593 }
594
595 sampling(u);
596 }
597
605 void Bimage::check_resolution(double& resolution)
606 {
607 Vector3<double> u(image->sampling());
608 if ( x > 1 && resolution < 2*u[0] ) resolution = 2*u[0];
609 if ( y > 1 && resolution < 2*u[1] ) resolution = 2*u[1];
610 if ( z > 1 && resolution < 2*u[2] ) resolution = 2*u[2];
611 if ( resolution > real_size()[0]/2.0 ) resolution = real_size()[0]/2.0;
612 }
613
623 bool Bimage::compatible(Bimage* p)
624 {
625 int non(0);
626
627 if ( c != p->c ) {
628 // cout << filename << " has an incompatible number of channels: " << c << endl;
629 cout << metadata["filename"] << " has an incompatible number of channels: " << c << endl;
630 non ++;
631 }
632
633 if ( datatype != p->datatype ) {
634 // cout << filename << " has an incompatible data type: " << datatype << endl;
635 cout << metadata["filename"] << " has an incompatible data type: " << datatype << endl;
636 non ++;
637 }
638
639 return (non==0);
640 }
641
648 void Bimage::meta_data_update()
649 {
650 if ( n <= 0 ) {
651 cerr << "Error in Bimage::meta_data_update: The number of images must be greater than 0" << endl;
652 return;
653 }
654
655 if ( verbose & VERB_DEBUG )
656 cout << "DEBUG Bimage::meta_data_update: Updating metadata" << endl;
657
658 metadata["version"] = BVERSION; // Version number
659 metadata["time"] = time(NULL);
660 metadata["user"] = get_user_name();
661
662 JSvalue arr(JSarray);
663 // vector<double> sam(3), ori(3), vw(4);
664
665 if ( metadata.exists("image") )
666 arr = metadata["image"].array();
667
668 for ( long i=0; i<n; ++i ) {
669 Bsub_image& si = image[i];
670 // sam = {si.sampling()[0], si.sampling()[1], si.sampling()[2]};
671 // ori = {si.origin()[0], si.origin()[1], si.origin()[2]};
672 // vw = {si.view()[0], si.view()[1], si.view()[2], si.view()[3]};
673 if ( i >= arr.size() )
674 arr.push_back(JSvalue(JSobject));
675 JSvalue& img = arr[i];
676 img["number"] = i+1;
677 // img["sampling"] = sam;
678 // img["origin"] = ori;
679 // img["view"] = vw;
680 img["sampling"] = si.sampling().array();
681 img["origin"] = si.origin().array();
682 img["view"] = si.view().array();
683 img["magnification"] = si.magnification();
684 img["background"] = si.background();
685 img["average"] = si.average();
686 img["standard_deviation"] = si.standard_deviation();
687 img["minimum"] = si.minimum();
688 img["maximum"] = si.maximum();
689 img["fom"] = si.FOM();
690 img["select"] = si.select();
691 }
692
693 metadata["image"] = arr;
694 }
695
702 void Bimage::update_from_meta_data()
703 {
704 if ( verbose & VERB_DEBUG )
705 cout << "DEBUG update_from_meta_data: converting JSON header" << endl;
706
707 vector<double> sam(3), ori(3), vw(4);
708 JSvalue arr(JSarray);
709
710 if ( metadata.exists("image") )
711 arr = metadata["image"].array();
712
713 for ( auto it = arr.begin(); it != arr.end(); ++it ) {
714 JSvalue& img = *it;
715 long i = img["number"].integer() - 1;
716 if ( i >= n ) break;
717 Bsub_image& si = image[i];
718 if ( img.exists("sampling") ) {
719 sam = img["sampling"].array_real();
720 si.sampling(sam);
721 }
722 if ( img.exists("origin") ) {
723 ori = img["origin"].array_real();
724 si.origin(ori);
725 }
726 if ( img.exists("view") ) {
727 vw = img["view"].array_real();
728 si.view(vw);
729 }
730 if ( img.exists("magnification") ) si.magnification(img["magnification"].real());
731 if ( img.exists("background") ) si.background(img["background"].real());
732 if ( img.exists("average") ) si.average(img["average"].real());
733 if ( img.exists("standard_deviation") ) si.standard_deviation(img["standard_deviation"].real());
734 if ( img.exists("minimum") ) si.minimum(img["minimum"].real());
735 if ( img.exists("maximum") ) si.maximum(img["maximum"].real());
736 if ( img.exists("fom") ) si.FOM(img["fom"].real());
737 if ( img.exists("select") ) si.select(img["select"].integer());
738 }
739
740 if ( verbose & VERB_DEBUG )
741 cout << "DEBUG update_from_meta_data: converting done" << endl;
742 }
743
748 void Bimage::meta_data_retain_one_image(long img_num)
749 {
750 JSvalue arr(JSarray);
751
752 if ( metadata.exists("image") )
753 arr = metadata["image"].array();
754 else return;
755
756 JSvalue img = arr[img_num];
757 JSvalue arrnu(JSarray);
758
759 img["number"] = 1;
760
761 arrnu.push_back(img);
762
763 metadata["image"] = arrnu;
764
765 // cout << "image number = " << img_num << tab << "new array = " << metadata["image"] << endl;
766 }
767
776 unsigned char* Bimage::data_alloc(long nbytes)
777 {
778 if ( !data_size() ) {
779 cerr << "Error in Bimage::data_alloc: Data size is zero!" << endl;
780 cerr << "(c=" << c << " x=" << x << " y=" << y << " z=" << z << " n=" << n << ")" << endl;
781 exit(-1);
782 }
783
784 long ds(datasize*data_type_size());
785 if ( datatype == Bit ) ds /= 8;
786
787 if ( nbytes != ds ) {
788 cerr << "Error in Bimage::data_alloc: Data size is not equal to the allocation requested!" << endl;
789 cerr << "(" << ds << " != " << nbytes << ")" << endl;
790 exit(-1);
791 }
792
793 if ( d.uc ) delete [] d.uc;
794
795 d.uc = new unsigned char[nbytes];
796
797 if ( !d.uc ) {
798 cerr << "Error: Image data not allocated! (" << nbytes << ")" << endl;
799 exit(-1);
800 }
801
802 for ( long j=0; j<nbytes; j++ ) d.uc[j] = 0;
803
804 data_size();
805
806 return d.uc;
807 }
808
822 unsigned char* Bimage::data_alloc(DataType type, CompoundType ctype, long nx,
823 long ny, long nz, long nn)
824 {
825 if ( image ) {
826 if ( n != nn ) {
827 delete[] image;
828 image = NULL;
829 }
830 }
831
832 data_type(type);
833
834 c = compound_type_size();
835 x = nx; y = ny; z = nz;
836
837 if ( datatype == Bit ) px = 8*((x-1)/8 + 1);
838
839 images(nn);
840
841 return data_alloc();
842 }
843
852 unsigned char* Bimage::data_assign(unsigned char* nudata)
853 {
854 if ( !nudata ) {
855 cerr << "Error: Image data not assigned!" << endl;
856 exit(-1);
857 }
858
859 if ( d.uc ) delete [] d.uc;
860
861 d.uc = nudata;
862
863 data_size();
864
865 if ( verbose & VERB_DEBUG )
866 cout << "DEBUG Bimage::data_assign: datasize=" << datasize << endl;
867
868 return d.uc;
869 }
870
874 void Bimage::data_delete()
875 {
876 if ( d.uc ) delete [] d.uc;
877
878 d.uc = NULL;
879 }
880
881
888 Bimage& Bimage::operator=(const Bimage& p)
889 {
890 // cout << "Assign image" << endl;
891 internal_copy(p);
892
893 // cout << "Copy image done" << endl;
894 return *this;
895 }
896
905 double Bimage::operator[](long j) const
906 {
907 if ( j >= datasize ) return 0;
908
909 switch ( datatype ) {
910 case Bit: return ((d.uc[j/8] << (j%8)) & 0x80) == 0x80;
911 case UCharacter: return d.uc[j];
912 case SCharacter: return d.sc[j];
913 case UShort: return d.us[j];
914 case Short: return d.ss[j];
915 case UInteger: return d.ui[j];
916 case Integer: return d.si[j];
917 case ULong: return d.ul[j];
918 case Long: return d.sl[j];
919 case Float: return d.f[j];
920 case Double: return d.d[j];
921 default: return 0;
922 }
923 }
924
937 double Bimage::get(long nn, long xx, long yy, long zz, long cc)
938 {
939 if ( nn >= n ) return 0;
940 if ( xx >= x ) return 0;
941 if ( yy >= y ) return 0;
942 if ( zz >= z ) return 0;
943
944 long j = (((nn*z + zz)*y + yy)*x + xx)*c + cc;
945
946 return (*this)[j];
947 }
948
959 double Bimage::get(long nn, Vector3<double> vox, long cc)
960 {
961 if ( nn >= n ) return 0;
962 if ( vox[0] < 0 || vox[0] > x-1 ) return 0;
963 if ( vox[1] < 0 || vox[1] > y-1 ) return 0;
964 if ( vox[2] < 0 || vox[2] > z-1 ) return 0;
965
966 long j = (((nn*z + (long)(vox[2]+0.5))*y + (long)(vox[1]+0.5))*x + (long)(vox[0]+0.5))*c + cc;
967
968 return (*this)[j];
969 }
970
980 double* Bimage::values(long nn, Vector3<double> vox)
981 {
982 long i;
983 double* values = new double[c];
984 for ( i=0; i<c; i++ ) values[i] = 0;
985
986 if ( nn >= n ) return values;
987 if ( vox[0] < 0 || vox[0] > x-1 ) return values;
988 if ( vox[1] < 0 || vox[1] > y-1 ) return values;
989 if ( vox[2] < 0 || vox[2] > z-1 ) return values;
990
991 long j = (((nn*z + (long)(vox[2]+0.5))*y + (long)(vox[1]+0.5))*x + (long)(vox[0]+0.5))*c;
992 for ( i=0; i<c; i++, j++ ) values[i] = (*this)[j];
993
994 return values;
995 }
996
1005 Complex<double> Bimage::complex(long j)
1006 {
1007 long i2 = 2*j;
1008 return Complex<double>((*this)[i2],(*this)[i2+1]);
1009 }
1010
1019 Vector3<double> Bimage::vector3(long j)
1020 {
1021 long i3 = 3*j;
1022 return Vector3<double>((*this)[i3],(*this)[i3+1],(*this)[i3+2]);
1023 }
1024
1033 RGB<double> Bimage::rgb(long j)
1034 {
1035 long i3 = 3*j;
1036 return RGB<double>((*this)[i3],(*this)[i3+1],(*this)[i3+2]);
1037 }
1038
1047 RGBA<double> Bimage::rgba(long j)
1048 {
1049 long i4 = 4*j;
1050 return RGBA<double>((*this)[i4],(*this)[i4+1],(*this)[i4+2],(*this)[i4+3]);
1051 }
1052
1061 CMYK<double> Bimage::cmyk(long j)
1062 {
1063 long i4 = 4*j;
1064 return CMYK<double>((*this)[i4],(*this)[i4+1],(*this)[i4+2],(*this)[i4+3]);
1065 }
1066
1067 TypePointer Bimage::fill_value(double v)
1068 {
1069 TypePointer fp;
1070 fp.uc = new unsigned char[data_type_size()];
1071
1072 switch ( datatype ) {
1073 case Bit: fp.uc[0] = (v)? 1: 0; break;
1074 case UCharacter: fp.uc[0] = (unsigned char)v; break;
1075 case SCharacter: fp.sc[0] = (signed char)v; break;
1076 case UShort: fp.us[0] = (unsigned short)v; break;
1077 case Short: fp.ss[0] = (short)v; break;
1078 case UInteger: fp.ui[0] = (unsigned int)v; break;
1079 case Integer: fp.si[0] = (int)v; break;
1080 case ULong: fp.ul[0] = (unsigned long)v; break;
1081 case Long: fp.sl[0] = (long)v; break;
1082 case Float: fp.f[0] = v; break;
1083 case Double: fp.d[0] = v; break;
1084 default: ;
1085 }
1086
1087 return fp;
1088 }
1089
1096 void Bimage::set(long j, double v)
1097 {
1098 if ( j >= datasize ) return;
1099
1100 long k;
1101
1102 if ( v < dtmin ) v = dtmin;
1103 else if ( v > dtmax ) v = dtmax;
1104
1105 switch ( datatype ) {
1106 case Bit: k = (j/x)*px + j%x; if ( 2*v > min+max ) d.uc[k/8] |= 0x80 >> k%8; break;
1107 case UCharacter: d.uc[j] = (unsigned char)v; break;
1108 case SCharacter: d.sc[j] = (signed char)v; break;
1109 case UShort: d.us[j] = (unsigned short)v; break;
1110 case Short: d.ss[j] = (short)v; break;
1111 case UInteger: d.ui[j] = (unsigned int)v; break;
1112 case Integer: d.si[j] = (int)v; break;
1113 case ULong: d.ul[j] = (unsigned long)v; break;
1114 case Long: d.sl[j] = (long)v; break;
1115 case Float: d.f[j] = v; break;
1116 case Double: d.d[j] = v; break;
1117 default: ;
1118 }
1119 }
1120
1129 void Bimage::set(long j, Complex<double> cv)
1130 {
1131 long i2 = 2*j;
1132
1133 set(i2++, cv.real());
1134 set(i2, cv.imag());
1135 }
1136
1145 void Bimage::set(long j, RGB<double> color)
1146 {
1147 long i3 = 3*j;
1148
1149 if ( i3 >= datasize ) return;
1150
1151 set(i3++, color.r());
1152 set(i3++, color.g());
1153 set(i3, color.b());
1154 }
1155
1164 void Bimage::set(long j, RGBA<double> color)
1165 {
1166 long i4 = 4*j;
1167
1168 if ( i4 >= datasize ) return;
1169
1170 set(i4++, color.r());
1171 set(i4++, color.g());
1172 set(i4++, color.b());
1173 set(i4, color.a());
1174 }
1175
1184 void Bimage::set(long j, CMYK<double> color)
1185 {
1186 long i4 = 4*j;
1187
1188 if ( i4 >= datasize ) return;
1189
1190 set(i4++, color.c());
1191 set(i4++, color.m());
1192 set(i4++, color[1]);
1193 set(i4, color.k());
1194 }
1195
1204 void Bimage::set(long j, Vector3<double> vec)
1205 {
1206 long i3 = 3*j;
1207
1208 if ( i3 >= datasize ) return;
1209
1210 set(i3++, vec[0]);
1211 set(i3++, vec[1]);
1212 set(i3, vec[2]);
1213 }
1214
1222 void Bimage::set(long j, View view)
1223 {
1224 long i4 = 4*j;
1225
1226 if ( i4 >= datasize ) return;
1227
1228 set(i4++, view[0]);
1229 set(i4++, view[1]);
1230 set(i4++, view[2]);
1231 set(i4, view.angle());
1232 }
1233
1244 void Bimage::add(double xx, double yy, double zz, long nn, double v)
1245 {
1246 long slicesize = x*y;
1247 long imgsize = slicesize*z;
1248 long ix = (long) xx;
1249 long iy = (long) yy;
1250 long iz = (long) zz;
1251 long jx, jy, jz, xk, yk, zk;
1252 double fx = xx - ix;
1253 double fy = yy - iy;
1254 double fz = zz - iz;
1255 double w;
1256
1257 for ( zk=0; zk<2; zk++, iz++ ) {
1258 fz = 1 - fz;
1259 jz = nn*imgsize + iz*slicesize + iy*x;
1260 for ( yk=0, jy=jz; yk<2; yk++, jy+=x ) {
1261 fy = 1 - fy;
1262 for ( xk=0, jx=jy+ix; xk<2; xk++, jx++ ) {
1263 fx = 1 - fx;
1264 w = fx*fy*fz;
1265 add(jx, v * w);
1266 }
1267 }
1268 }
1269 }
1270
1281 void Bimage::set_max(double xx, double yy, double zz, long nn, double v)
1282 {
1283 long slicesize = x*y;
1284 long imgsize = slicesize*z;
1285 long ix = (long) xx;
1286 long iy = (long) yy;
1287 long iz = (long) zz;
1288 long jx, jy, jz, xk, yk, zk;
1289
1290 for ( zk=0; zk<2; zk++, iz++ ) {
1291 jz = nn*imgsize + iz*slicesize + iy*x;
1292 for ( yk=0, jy=jz; yk<2; yk++, jy+=x ) {
1293 for ( xk=0, jx=jy+ix; xk<2; xk++, jx++ ) {
1294 if ( (*this)[jx] < v ) set(jx, v);
1295 }
1296 }
1297 }
1298 }
1299
1312 double Bimage::average2D(long cc, double xf, double yf,
1313 double zf, long nn, double iscale)
1314 {
1315 long zz = (long) zf;
1316 long j, ix, iy, num(0), ij = (nn*z + zz)*y*x;
1317 double xx, yy, avg(0);
1318 double xmax = xf + iscale - 0.5, ymax = yf + iscale - 0.5;
1319
1320 for ( yy=yf; yy < ymax; yy += 1 ) {
1321 iy = (long) yy;
1322 if ( iy < y ) for ( xx=xf; xx < xmax; xx += 1 ) {
1323 ix = (long) xx;
1324 if ( ix < x ) {
1325 j = (ij + iy*x + ix)*c + cc;
1326 avg += (*this)[j];
1327 num++;
1328 }
1329 }
1330 }
1331
1332 if ( num ) avg /= num;
1333
1334 return avg;
1335 }
1336
1349 double Bimage::average(long cc, double xf, double yf,
1350 double zf, long nn, double iscale)
1351 {
1352 long j, ix, iy, iz, ij, num(0);
1353 double xx, yy, zz, avg(0);
1354 double xmax = xf + iscale - 0.5;
1355 double ymax = yf + iscale - 0.5;
1356 double zmax = zf + iscale - 0.5;
1357 if ( xmax > x ) xmax = x;
1358 if ( ymax > y ) ymax = y;
1359 if ( zmax > z ) zmax = z;
1360
1361 for ( zz=zf; zz < zmax; zz += 1 ) {
1362 iz = (long) zz;
1363 ij = (nn*z + iz)*y*x;
1364 for ( yy=yf; yy < ymax; yy += 1 ) {
1365 iy = (long) yy;
1366 for ( xx=xf; xx < xmax; xx += 1 ) {
1367 ix = (long) xx;
1368 j = (ij + iy*x + ix)*c + cc;
1369 avg += (*this)[j];
1370 num++;
1371 }
1372 }
1373 }
1374
1375 if ( num ) avg /= num;
1376
1377 return avg;
1378 }
1379
1392 double Bimage::interpolate(long cc, double xx,
1393 double yy, double zz, long nn, double fill) const
1394 {
1395 // cout << cc << tab << xx << tab << yy << tab << zz << tab << nn << endl;
1396 if ( cc >= c ) return fill;
1397 if ( xx < 0 || xx >= x ) return fill;
1398 if ( yy < 0 || yy >= y ) return fill;
1399 if ( zz < 0 || zz >= z ) return fill;
1400 if ( nn >= n ) return fill;
1401
1402 long ix = (long) xx;
1403 long iy = (long) yy;
1404 long iz = (long) zz;
1405
1406 long nx = (x < ix + 2)? 1: 2;
1407 long ny = (y < iy + 2)? 1: 2;
1408 long nz = (z < iz + 2)? 1: 2;
1409
1410 long i, xk, yk, zk;
1411 double fx = xx - ix;
1412 double fy = yy - iy;
1413 double fz = zz - iz;
1414
1415 double value(0), w(0), ws(0), wyz;
1416
1417 iz = (nn*z + iz)*y;
1418
1419 for ( zk=0; zk<nz; zk++, iz+=y ) {
1420 fz = 1.0L - fz;
1421 iy = (long) yy;
1422 iy = (iz + iy)*x;
1423 for ( yk=0; yk<ny; yk++, iy+=x ) {
1424 fy = 1.0L - fy;
1425 ix = (long) xx;
1426 i = (iy + ix)*c + cc;
1427 wyz = fy*fz;
1428 for ( xk=0; xk<nx; xk++, i+=c ) {
1429 fx = 1.0L - fx;
1430 w = fx*wyz;
1431 ws += w;
1432 value += (*this)[i] * w;
1433 }
1434 }
1435 }
1436
1437 if ( ws ) value /= ws;
1438 else value = fill;
1439
1440 return value;
1441 }
1442 /*
1443 double Bimage::interpolate(long cc, double xx,
1444 double yy, double zz, long nn, double fill) const
1445 {
1446 // cout << cc << tab << xx << tab << yy << tab << zz << tab << nn << endl;
1447 if ( cc >= c ) return fill;
1448 if ( xx < 0 || xx >= x ) return fill;
1449 if ( yy < 0 || yy >= y ) return fill;
1450 if ( zz < 0 || zz >= z ) return fill;
1451 if ( nn >= n ) return fill;
1452
1453 long ix = (long) xx;
1454 long iy = (long) yy;
1455 long iz = (long) zz;
1456 long xc(x*c), xyc(xc*y), xyzc(xyc*z);
1457 double fx = xx - ix;
1458 double fy = yy - iy;
1459 double fz = zz - iz;
1460 double value(0), w(0), ws(0), wyz;
1461
1462 nn *= xyzc;
1463 iz *= xyc;
1464 iy *= xc;
1465 ix *= c;
1466 long iz1 = (iz < xyzc - xyc)? iz+xyc: iz;
1467 long iy1 = (iy < xyc - xc)? iy+xc: iy;
1468 long ix1 = (ix < xc - c)? ix+c: ix;
1469
1470 for ( ; iz<iz1; iz+=xyc ) {
1471 fz = 1 - fz;
1472 for ( iy = ((long) yy)*xc; iy<iy1; iy+=xc ) {
1473 fy = 1 - fy;
1474 wyz = fy*fz;
1475 for ( ix = ((long) xx)*c + cc; ix<ix1; ix+=c ) {
1476 fx = 1 - fx;
1477 w = fx*wyz;
1478 ws += w;
1479 value += (*this)[nn+iz+iy+ix] * w;
1480 }
1481 }
1482 }
1483
1484 if ( ws ) value /= ws;
1485
1486 return value;
1487 }
1488 */
1489
1502 double Bimage::interpolate_wrap(long cc, double xx,
1503 double yy, double zz, long nn) const
1504 {
1505 // cout << cc << tab << xx << tab << yy << tab << zz << tab << nn << endl;
1506 if ( cc >= c ) return 0;
1507 if ( nn >= n ) return 0;
1508 while ( xx < 0 ) xx += x;
1509 while ( yy < 0 ) yy += y;
1510 while ( zz < 0 ) zz += z;
1511 while ( xx >= x ) xx -= x;
1512 while ( yy >= y ) yy -= y;
1513 while ( zz >= z ) zz -= z;
1514
1515 long nx(2), ny(2), nz(2);
1516 if ( x < 2 ) nx = 1;
1517 if ( y < 2 ) ny = 1;
1518 if ( z < 2 ) nz = 1;
1519
1520 long ix = (long) xx;
1521 long iy = (long) yy;
1522 long iz = (long) zz;
1523 long i, in(nn*z), xk, yk, zk, jy, jz;
1524 double fx = xx - ix;
1525 double fy = yy - iy;
1526 double fz = zz - iz;
1527
1528 double value(0), wyz;
1529
1530 for ( zk=0; zk<nz; zk++, iz++ ) {
1531 if ( iz >= z ) iz -= z;
1532 fz = 1 - fz;
1533 jz = (in + iz)*y;
1534 iy = (long) yy;
1535 for ( yk=0; yk<ny; yk++, iy++ ) {
1536 if ( iy >= y ) iy -= y;
1537 fy = 1 - fy;
1538 jy = (jz + iy)*x;
1539 ix = (long) xx;
1540 wyz = fy*fz;
1541 for ( xk=0; xk<nx; xk++, ix++ ) {
1542 if ( ix >= x ) ix -= x;
1543 i = (jy + ix)*c + cc;
1544 fx = 1 - fx;
1545 value += (*this)[i] * (fx*wyz);
1546 }
1547 }
1548 }
1549
1550 return value;
1551 }
1552
1560 long Bimage::data_type_bits() const
1561 {
1562 long bits(0);
1563
1564 switch ( datatype ) {
1565 case Bit: bits = 1; break;
1566 case UCharacter: case SCharacter: bits = 8*sizeof(char); break;
1567 case UShort: case Short: bits = 8*sizeof(short); break;
1568 case UInteger: case Integer: bits = 8*sizeof(int); break;
1569 case ULong: case Long: bits = 8*sizeof(long); break;
1570 case Float: bits = 8*sizeof(float); break;
1571 case Double: bits = 8*sizeof(double); break;
1572 default: bits = 0;
1573 }
1574
1575 return bits;
1576 }
1577
1585 long Bimage::data_type_size() const
1586 {
1587 long typesize(0);
1588
1589 switch ( datatype ) {
1590 case Bit:
1591 case UCharacter: case SCharacter: typesize = sizeof(char); break;
1592 case UShort: case Short:typesize = sizeof(short); break;
1593 case UInteger: case Integer: typesize = sizeof(int); break;
1594 case ULong: case Long: typesize = sizeof(long); break;
1595 case Float: typesize = sizeof(float); break;
1596 case Double: typesize = sizeof(double); break;
1597 default: typesize = 0;
1598 }
1599
1600 return typesize;
1601 }
1602
1611 double Bimage::data_type_min()
1612 {
1613 double min(0);
1614
1615 switch ( datatype ) {
1616 case Bit: min = 0; break;
1617 case UCharacter: min = 0; break;
1618 case SCharacter: min = -128; break;
1619 case UShort: min = 0; break;
1620 case Short: min = SHRT_MIN; break;
1621 case UInteger: min = 0; break;
1622 case Integer: min = INT_MIN; break;
1623 case ULong: min = 0; break;
1624 case Long: min = LONG_MIN; break;
1625 case Float: min = -FLT_MAX; break;
1626 case Double: min = -DBL_MAX; break;
1627 default: break;
1628 }
1629
1630 return min;
1631 }
1632
1641 double Bimage::data_type_max()
1642 {
1643 double max(0);
1644
1645 switch ( datatype ) {
1646 case Bit: max = 1; break;
1647 case UCharacter: max = 255; break;
1648 case SCharacter: max = 127; break;
1649 case UShort: max = USHRT_MAX; break;
1650 case Short: max = SHRT_MAX; break;
1651 case UInteger: max = UINT_MAX; break;
1652 case Integer: max = INT_MAX; break;
1653 case ULong: max = ULONG_MAX; break;
1654 case Long: max = LONG_MAX; break;
1655 case Float: max = FLT_MAX; break;
1656 case Double: max = DBL_MAX; break;
1657 default: break;
1658 }
1659
1660 return max;
1661 }
1662
1667 Bstring Bimage::data_type_string()
1668 {
1669 Bstring string;
1670
1671 switch ( datatype ) {
1672 case Bit: string = "bit"; break;
1673 case UCharacter: string = "unsigned char"; break;
1674 case SCharacter: string = "signed char"; break;
1675 case UShort: string = "unsigned short"; break;
1676 case Short: string = "short"; break;
1677 case UInteger: string = "unsigned int"; break;
1678 case Integer: string = "int"; break;
1679 case ULong: string = "unsigned long"; break;
1680 case Long: string = "long"; break;
1681 case Float: string = "float"; break;
1682 case Double: string = "double"; break;
1683 default: string = "unknown";
1684 }
1685
1686 return string;
1687 }
1688
1693 Bstring Bimage::compound_type_string()
1694 {
1695 Bstring string;
1696
1697 switch ( compoundtype ) {
1698 case TSimple: string = "Simple"; break;
1699 case TComplex: string = "Complex"; break;
1700 case TVector3: string = "Vector3"; break;
1701 case TView: string = "View"; break;
1702 case TRGB: string = "RGB"; break;
1703 case TRGBA: string = "RGBA"; break;
1704 case TCMYK: string = "CMYK"; break;
1705 default: string = "unknown"; break;
1706 }
1707
1708 return string;
1709 }
1710
1718 void Bimage::fix_type()
1719 {
1720 switch ( datatype ) {
1721 case UCharacter: datatype = SCharacter; break;
1722 case SCharacter: datatype = UCharacter; break;
1723 case UShort: datatype = Short; break;
1724 case Short: datatype = UShort; break;
1725 case UInteger: datatype = Integer; break;
1726 case Integer: datatype = UInteger; break;
1727 case ULong: datatype = Long; break;
1728 case Long: datatype = ULong; break;
1729 default: break;
1730 }
1731
1732 data_type(datatype);
1733 }
1734
1743 void Bimage::change_type(char letter)
1744 {
1745 DataType nutype;
1746
1747 switch ( letter ) {
1748 case '1': nutype = Bit; break;
1749 case 'b': nutype = UCharacter; break;
1750 case 'c': nutype = SCharacter; break;
1751 case 'u': nutype = UShort; break;
1752 case 's': nutype = Short; break;
1753 case 'j': nutype = UInteger; break;
1754 case 'i': nutype = Integer; break;
1755 case 'k': nutype = ULong; break;
1756 case 'l': nutype = Long; break;
1757 case 'f': nutype = Float; break;
1758 case 'd': nutype = Double; break;
1759 case 'S': nutype = Short; break;
1760 case 'I': nutype = Integer; break;
1761 case 'F': nutype = Float; break;
1762 case 'D': nutype = Double; break;
1763 default: nutype = Unknown_Type; break;
1764 }
1765
1766 change_type(nutype);
1767 }
1768
1773 void Bimage::change_type(char* string)
1774 {
1775 if ( strlen(string) == 1 ) {
1776 change_type(string[0]);
1777 return;
1778 }
1779
1780 size_t j;
1781 DataType nutype = Unknown_Type;
1782
1783 for ( j=0; j<strlen(string); j++ ) string[j] = tolower(string[j]);
1784
1785 if ( strstr(string, "unsigned") ) {
1786 if ( strstr(string, "char") ) nutype = UCharacter;
1787 else if ( strstr(string, "short") ) nutype = UShort;
1788 else if ( strstr(string, "int") ) nutype = UInteger;
1789 else if ( strstr(string, "long") ) nutype = ULong;
1790 } else {
1791 if ( strstr(string, "bit") ) nutype = Bit;
1792 else if ( strstr(string, "byte") ) nutype = UCharacter;
1793 else if ( strstr(string, "char") ) nutype = SCharacter;
1794 else if ( strstr(string, "short") ) nutype = Short;
1795 else if ( strstr(string, "int") ) nutype = Integer;
1796 else if ( strstr(string, "long") ) nutype = Long;
1797 else if ( strstr(string, "float") ) nutype = Float;
1798 else if ( strstr(string, "double") ) nutype = Double;
1799 }
1800
1801 change_type(nutype);
1802 }
1803
1808 void Bimage::change_type(DataType nutype)
1809 {
1810 if ( datatype == nutype || nutype == Unknown_Type ) return;
1811
1812 if ( max - min < 1e-37 ) max = min + 1;
1813
1814 long j, k, l, m;
1815 long oldtypesize = data_type_size();
1816 double v(0);
1817 // double omn = dtmin;
1818
1819 TypePointer p = d;
1820
1821 DataType oldtype = datatype;
1822
1823 data_type(nutype);
1824 double mn = dtmin;
1825 double mx = dtmax;
1826
1827 if ( datatype == Bit ) px = 8*((x-1)/8+1);
1828
1829 long typesize = data_type_size();
1830
1831 long allocsize = alloc_size();
1832
1833 if ( verbose & VERB_DEBUG )
1834 cout << "DEBUG Bimage::change_type: datatype=" << datatype << " datasize=" << datasize << endl;
1835
1836 double scale(1), shift(0);
1837
1838 // Integer switches between signed and unsigned
1839 if ( datatype >= UCharacter && datatype <= Long ) {
1840 if ( oldtype >= Float ) { // floating point to integer
1841 if ( min >= 0 ) scale = mx/max;
1842 else {
1843 scale = (mx - mn)/(max - min);
1844 shift = mn - min*scale;
1845 }
1846 if ( compoundtype == TComplex && datatype == Short ) {
1847 scale = 0.5*mx/max;
1848 shift = 0;
1849 }
1850 } else {
1851 if ( min == 0 && max == 1 ) { // masks
1852 scale = 1;
1853 shift = 0;
1854 } else if ( oldtypesize == typesize ) {
1855 if ( min >= mn && max <= mx ) {
1856 shift = 0;
1857 } else if ( datatype == oldtype + 1 ) { // unsigned -> signed
1858 shift = mn;
1859 } else if ( datatype == oldtype - 1 ) { // signed -> unsigned
1860 shift = -min;
1861 }
1862 } else if ( oldtype > datatype && ( min < mn || max > mx ) ) { // larger to smaller integer
1863 scale = (mx - mn)/(max - min);
1864 shift = mn - min*scale;
1865 }
1866 }
1867 }
1868
1869 if ( datatype == Float && oldtype == Double && ( min < mn || max > mx ) ) {
1870 scale = (mx - mn)/(max - min);
1871 }
1872
1873 if ( verbose & VERB_DEBUG )
1874 cout << "DEBUG Bimage::change_type: scale=" << scale << " shift=" << shift << endl;
1875
1876 if ( oldtypesize != typesize || oldtype == Bit || datatype == Bit ) {
1877 if ( verbose & VERB_DEBUG )
1878 cout << "DEBUG Bimage::change_type: allocsize=" << allocsize << endl;
1879 d.uc = new unsigned char[allocsize];
1880 for ( j=0; j<allocsize; j++ ) d.uc[j] = 0;
1881 }
1882
1883 if ( oldtype == Bit ) {
1884 for ( j=l=0; l<n*y*z; l++ )
1885 for ( k=0, m=l*px; k<x; k++, j++, m++ ) set(j, ((p.uc[m/8] << (m%8)) & 0x80) == 0x80);
1886 } else for ( j=l=0; j<datasize; j++, l++ ) {
1887 switch ( oldtype ) {
1888 case UCharacter: v = p.uc[j]; break;
1889 case SCharacter: v = p.sc[j]; break;
1890 case UShort: v = p.us[j]; break;
1891 case Short: v = p.ss[j]; break;
1892 case UInteger: v = p.ui[j]; break;
1893 case Integer: v = p.si[j]; break;
1894 case ULong: v = p.ul[j]; break;
1895 case Long: v = p.sl[j]; break;
1896 case Float: v = p.f[j]; break;
1897 case Double: v = p.d[j]; break;
1898 default: ;
1899 }
1900 v = scale*v + shift;
1901 k = j;
1902 if ( datatype == Bit ) {
1903 if ( l >= x ) {
1904 for ( ; l<px; l++, k++ ) ;
1905 l = 0;
1906 }
1907 }
1908 set(k, v);
1909 }
1910
1911 if ( oldtypesize != typesize || oldtype == Bit || datatype == Bit )
1912 delete [] p.uc;
1913
1914 if ( statistics() )
1915 cerr << tab << "in Bimage::change_type" << endl;
1916 }
1917
1924 void Bimage::split_channels()
1925 {
1926 long nn, cc, j, m, k;
1927 long tsize = data_type_size();
1928 long imgsize = x*y*z;
1929 unsigned char* nudata = new unsigned char[alloc_size()];
1930
1931 for ( nn=k=0; nn<n; nn++ ) {
1932 for ( j=0; j<imgsize; j++ ) {
1933 for ( cc=0, m=nn*imgsize+j; cc<c; cc++, k+=tsize, m+=imgsize ) {
1934 memcpy(nudata+m*tsize, d.uc+k, tsize);
1935 }
1936 }
1937 }
1938
1939 data_assign(nudata);
1940
1941 Bsub_image* nusub = new Bsub_image[n*c];
1942
1943 if ( image ) {
1944 for ( nn=j=0; nn<n; nn++ )
1945 for ( cc=0; cc<c; cc++, j++ )
1946 nusub[j] = image[nn];
1947 delete[] image;
1948 }
1949
1950 image = nusub;
1951
1952 compoundtype = TSimple;
1953 n *= c;
1954 c = 1;
1955
1956 statistics();
1957 }
1958
1965 void Bimage::combine_channels(long nc)
1966 {
1967 if ( nc < 1 ) nc = n;
1968
1969 long nun, nn, cc, j, m, k;
1970 long tsize = data_type_size();
1971 long imgsize = x*y*z;
1972 unsigned char* nudata = new unsigned char[alloc_size()];
1973
1974 nun = n/nc;
1975
1976 for ( nn=k=0; nn<nun; nn++ ) {
1977 for ( j=0; j<imgsize; j++ ) {
1978 for ( cc=0, m=nn*imgsize*nc+j; cc<nc; cc++, k+=tsize, m+=imgsize ) {
1979 memcpy(nudata+k*tsize, d.uc+m, tsize);
1980 }
1981 }
1982 }
1983
1984 data_assign(nudata);
1985
1986 Bsub_image* nusub = new Bsub_image[nun];
1987
1988 if ( image ) {
1989 for ( nn=j=0; nn<nun; nn++, j+=nc )
1990 nusub[nn] = image[j];
1991 delete[] image;
1992 }
1993
1994 image = nusub;
1995
1996 if ( nc == 2 ) compoundtype = TComplex;
1997 else if ( nc == 3 ) compoundtype = TRGB;
1998 else if ( nc == 4 ) compoundtype = TRGBA;
1999 else compoundtype = TMulti;
2000 n = nun;
2001 c = nc;
2002
2003 statistics();
2004 }
2005
2006
2011 void Bimage::zero_fourier_origin()
2012 {
2013 long j, nn;
2014 long imagesize = x*y*z;
2015 Complex<double> cv;
2016
2017 for ( j=nn=0; nn<n; nn++, j+=imagesize ) set(j, cv);
2018
2019 }
2020
2021
2036 double Bimage::maximum_included_radius()
2037 {
2038 double max_radius;
2039 long min_dimension(x);
2040 if ( (y > 1) && (y < min_dimension) ) min_dimension = y;
2041 if ( (z > 1) && (z < min_dimension) ) min_dimension = z;
2042
2043 max_radius = (min_dimension - 1)/2;
2044
2045 return max_radius;
2046 }
2047
2052 int Bimage::slices_to_images()
2053 {
2054 if ( z == 1 ) return 0;
2055
2056 if ( n > 1 ) {
2057 cerr << "Error: " << metadata["filename"] << " is already a multi-image file!" << endl;
2058 error_show("Bimage::slices_to_images", __FILE__, __LINE__);
2059 return -1;
2060 }
2061
2062 if ( verbose & VERB_DEBUG )
2063 cout << "DEBUG Bimage::slices_to_images: " << z << " slices to images" << endl;
2064
2065 long nn;
2066 Bsub_image subimg = image[0];
2067
2068 if ( image ) delete [] image;
2069
2070 n = z;
2071 z = 1;
2072
2073 image = new Bsub_image[n];
2074
2075 for ( nn=0; nn<n; nn++ )
2076 image[nn] = subimg;
2077
2078 /* if ( verbose & VERB_DEBUG )
2079 cout << "DEBUG Bimage::slices_to_images: metadata:" << endl << metadata << endl;
2080
2081 for ( nn=1; nn<n; nn++ )
2082 metadata["image"].array().push_back(metadata["image"][0]);
2083 */
2084 origin(default_origin());
2085
2086 return 0;
2087 }
2088
2093 int Bimage::images_to_slices()
2094 {
2095 if ( z > 1 ) {
2096 // cerr << "Error: " << filename << " is already a 3D image file!" << endl;
2097 cerr << "Error: " << metadata["filename"] << " is already a 3D image file!" << endl;
2098 error_show("Bimage::images_to_slices", __FILE__, __LINE__);
2099 return -1;
2100 }
2101
2102 if ( verbose & VERB_DEBUG )
2103 cout << "DEBUG Bimage::images_to_slices: " << n << " images to slices" << endl;
2104
2105 Bsub_image subimg = image[0];
2106
2107 if ( image ) delete [] image;
2108
2109 z = n;
2110 n = 1;
2111
2112 image = new Bsub_image[n];
2113
2114 image[0] = subimg;
2115
2116 // vector<JSvalue>& arr = metadata["image"].array();
2117 // arr.erase(arr.begin()+1, arr.end());
2118
2119 origin(default_origin());
2120
2121 return 0;
2122 }
2123
2134 long Bimage::delete_images(Bstring list, int retain)
2135 {
2136 long ni, no, ns(0);
2137 int* imgnum = new int[n];
2138
2139 select_numbers(list, n, imgnum);
2140
2141 for ( ni=0; ni<n; ni++ ) if ( imgnum[ni] ) ns++;
2142 if ( !retain ) ns = n - ns;
2143
2144 long imgsize = x*y*z*c*data_type_size();
2145
2146 Bsub_image* subimg = new Bsub_image[ns];
2147 unsigned char* nudata = new unsigned char[ns*imgsize];
2148
2149 for ( ni=no=0; ni<n; ni++ ) if ( retain == imgnum[ni] ) {
2150 if ( verbose & VERB_DEBUG )
2151 cout << "DEBUG delete_images: retaining " << ni << endl;
2152 memcpy(nudata+no*imgsize, d.uc+ni*imgsize, imgsize);
2153 subimg[no] = image[ni];
2154 no++;
2155 }
2156
2157 delete[] imgnum;
2158
2159 delete[] image;
2160 image = subimg;
2161 n = ns;
2162
2163 data_assign(nudata);
2164
2165 return ns;
2166 }
2167
2168 long Bimage::select_images(Bstring list)
2169 {
2170 return delete_images(list, 1);
2171 }
2172
2188 unsigned char* Bimage::read_data(ifstream* fimg, int img_select, int sb, int vax, long pad)
2189 {
2190 if ( page_size().volume() < 1 ) page_size(x, y, z);
2191
2192 // If only half of a transform is stored, it need to be handled
2193 long xstore = x;
2194 long xpage = px;
2195 if ( fouriertype == Hermitian || fouriertype == CentHerm ) {
2196 xstore = x/2 + 1;
2197 if ( px > xstore ) xpage = xstore;
2198 }
2199
2200 if ( datatype == Bit ) {
2201 xstore = xpage = (x - 1)/8 + 1;
2202 page_size(8*xstore, 1, 1);
2203 }
2204
2205 // Reset select to get the correct offset
2206 if ( img_select < 0 ) img_select = 0;
2207
2208 long i, iz, iy, j, jz, jy, nn, xx, yy, zz, pxx, pyy, pzz, npages, off;
2209 long datatypesize = data_type_size();
2210 long elementsize = datatypesize*c;
2211 long datasize = n*xstore*y*z*elementsize;
2212 long pagesize = xpage*py*pz*elementsize;
2213 long readsize, pagemax = 1073741824;
2214 unsigned char* data = data_alloc(datasize);
2215 unsigned char* page = NULL;
2216
2217 if ( verbose & VERB_DEBUG ) {
2218 cout << "DEBUG Bimage::read_data: type size=" << datatypesize << endl;
2219 cout << "DEBUG Bimage::read_data: data size: " << size() << " c=" << c << " n=" << n << " (" << datasize << ")" << endl;
2220 cout << "DEBUG Bimage::read_data: page size: " << page_size() << " (" << pagesize << ")" << endl;
2221 cout << "DEBUG Bimage::read_data: sb=" << sb << " vax=" << vax << " offset=" << offset << endl;
2222 }
2223
2224 if ( !data ) {
2225 error_show("No image data block allocated!", __FILE__, __LINE__);
2226 return NULL;
2227 }
2228
2229 if ( x == px && y == py && z == pz ) { // 3D block
2230 off = offset + img_select*(pagesize + pad);
2231 if ( verbose & VERB_DEBUG )
2232 cout << "DEBUG Bimage::read_data: Reading 3D blocks: off=" << off << " pad=" << pad << endl;
2233 fimg->seekg(off);
2234 for ( nn=0; nn<n; nn++ ) {
2235 for ( j=0; j<pagesize; j+=pagemax ) {
2236 readsize = pagesize - j;
2237 if ( readsize > pagemax ) readsize = pagemax;
2238 fimg->read((char *) (data + nn*pagesize + j), readsize);
2239 }
2240 if ( pad ) fimg->seekg(pad, ios_base::cur);
2241 }
2242 } else if ( x == px && y == py && pz == 1 ) { // 2D page (MFF)
2243 off = offset + img_select*z*(pagesize + pad);
2244 if ( verbose & VERB_DEBUG )
2245 cout << "DEBUG Bimage::read_data: Reading 2D pages: off=" << off << " pad=" << pad << endl;
2246 fimg->seekg(off);
2247 for ( nn=0; nn<n; nn++ ) {
2248 for ( pzz=0; pzz<z; pzz+=pz ) {
2249 i = (nn*z + pzz)*pagesize;
2250 fimg->read((char *) (data + i), pagesize);
2251 if ( pad ) fimg->seekg(pad, ios_base::cur);
2252 }
2253 }
2254 } else { // More complicated paging (DSN6 and BRIX)
2255 off = offset;
2256 if ( verbose & VERB_DEBUG )
2257 cout << "DEBUG Bimage::read_data: Reading single values: pagesize=" <<
2258 pagesize << " off=" << off << " pad=" << pad << endl;
2259 npages = 1;
2260 npages *= (z - 1)/pz + 1;
2261 npages *= (y - 1)/py + 1;
2262 npages *= (xstore - 1)/xpage + 1;
2263 off = offset + img_select*npages*(pagesize + pad);
2264 fimg->seekg(off);
2265 page = new unsigned char[pagesize];
2266 for ( nn=0; nn<n; nn++ ) {
2267 for ( pzz=0; pzz<z; pzz+=pz ) {
2268 for ( pyy=0; pyy<y; pyy+=py ) {
2269 for ( pxx=0; pxx<xstore; pxx+=xpage ) { //cout << pxx << tab << pyy << tab << pzz << endl;
2270 fimg->read((char *)page, pagesize);
2271 if ( sb > 1 )
2272 for ( i=0; i<pagesize; i+=sb ) swapbytes(page+i, sb);
2273 for ( zz=0; zz<pz && zz<z-pzz; zz++ ) {
2274 iz = (nn*z + zz + pzz)*y;
2275 jz = zz*py;
2276 for ( yy=0; yy<py && yy<y-pyy; yy++ ) {
2277 iy = (iz + yy + pyy)*xstore;
2278 jy = (jz + yy)*xpage;
2279 for ( xx=0; xx<xpage && xx<xstore-pxx; xx++ ) { //cout << xx << tab << yy << tab << zz << endl;
2280 i = (iy + xx + pxx)*elementsize;
2281 j = (jy + xx)*elementsize;
2282 memcpy(data+i, page+j, elementsize);
2283 }
2284 }
2285 }
2286 if ( pad ) fimg->seekg(pad, ios_base::cur);
2287 }
2288 }
2289 }
2290 }
2291 if ( page ) delete [] page;
2292 }
2293
2294 // Convert vax format and swap bytes if required
2295 if ( vax && sb < 2 && ( datatype == Float ) ) {
2296 if ( verbose & VERB_DEBUG )
2297 cout << "DEBUG Bimage::read_data: Converting vax image data with sb = " << sb << endl;
2298 for ( i=0; i<datasize; i+=4 )
2299 vax2ieee(data+i, 1-sb);
2300 } else if ( datatypesize > 1 ) {
2301 if ( sb == 1 ) {
2302 if ( verbose & VERB_DEBUG )
2303 cout << "DEBUG Bimage::read_data: Swapping image data with typesize = " << datatypesize << endl;
2304 for ( i=0; i<datasize; i+=datatypesize )
2305 swapbytes(data+i, datatypesize);
2306 } else if ( sb > 1 ) {
2307 if ( verbose & VERB_DEBUG )
2308 cout << "DEBUG Bimage::read_data: Swapping image data with typesize = " << sb << endl;
2309 for ( i=0; i<datasize; i+=sb )
2310 swapbytes(data+i, sb);
2311 }
2312 }
2313
2314 if ( verbose & VERB_DEBUG )
2315 cout << "DEBUG Bimage::read_data: Finished reading and converting data" << endl;
2316
2317 return data;
2318 }
2319
2320 int Bimage::write(Bstring& fn)
2321 {
2322 if ( verbose )
2323 cout << "Write image to " << fn << endl;
2324
2325 ofstream fimg(fn.c_str());
2326 if ( fimg.fail() ) return -1;
2327
2328 fimg.write((char *)&datatype, 8);
2329 fimg.write((char *)&c, 5*8);
2330 fimg.write((char *)d.uc, alloc_size());
2331
2332 fimg.close();
2333
2334 return 0;
2335 }
2336
2337 int Bimage::unpack_transform(unsigned char* data, FourierType tf)
2338 {
2339 return unpack_transform(-1, data, tf);
2340 }
2341
2342 int Bimage::unpack_transform(int img_select, unsigned char* data, FourierType tf)
2343 {
2344 if ( tf <= Standard ) {
2345 cerr << "Error: The transform is not in the correct format to unpack!" << endl;
2346 exit(-1);
2347 }
2348
2349 if ( verbose & VERB_PROCESS )
2350 cout << "Unpacking Fourier transform: " << tf << endl << endl;
2351
2352 long i, h, xx, yy, zz, nn, hx, hy, hz;
2353 long xstore = x, ox(0), oy(0), oz(0);
2354 long elsize = c*data_type_size();
2355 Complex<double> cv;
2356
2357 long nmin = (img_select >= 0)? img_select: 0;
2358 long nmax = (img_select >= 0)? img_select: n - 1;
2359
2360 switch ( tf ) {
2361 case Centered:
2362 ox = x/2;
2363 oy = y/2;
2364 oz = z/2;
2365 break;
2366 case Hermitian:
2367 xstore = x/2 + 1;
2368 break;
2369 case CentHerm:
2370 oy = y/2;
2371 oz = z/2;
2372 xstore = x/2 + 1;
2373 break;
2374 default: break;
2375 }
2376
2377 if ( verbose & VERB_DEBUG )
2378 cout << "DEBUG Bimage::unpack_transform: Element size = " << elsize << endl;
2379
2380 // cout << "xstore = " << xstore << endl;
2381
2382 // Transfer the data
2383 for ( nn=nmin; nn<=nmax; nn++ ) {
2384 for ( hz=0; hz<z; hz++ ) {
2385 zz = (hz>=oz)? hz - oz: z + hz - oz;
2386 for ( hy=0; hy<y; hy++ ) {
2387 yy = (hy>=oy)? hy - oy: y + hy - oy;
2388 for ( hx=0; hx<xstore; hx++, data+=elsize ) {
2389 xx = (hx>=ox)? hx - ox: x + hx - ox;
2390 i = index(xx, yy, zz, nn);
2391 memcpy(data_pointer() + i*elsize, data, elsize);
2392 }
2393 }
2394 }
2395 }
2396
2397 // Fill in the hermitian/friedel partners
2398 if ( xstore < x ) {
2399 for ( nn=nmin; nn<=nmax; nn++ ) {
2400 for ( zz=0; zz<z; zz++ ) {
2401 hz = (zz)? z - zz: 0;
2402 for ( yy=0; yy<y; yy++ ) {
2403 hy = (yy)? y - yy: 0;
2404 for ( xx=xstore; xx<x; xx++ ) {
2405 hx = x - xx;
2406 i = index(xx, yy, zz, nn);
2407 h = index(hx, hy, hz, nn);
2408 cv = complex(h);
2409 cv = cv.conj();
2410 set(i, cv);
2411 }
2412 }
2413 }
2414 }
2415 }
2416
2417 fourier_type(Standard);
2418
2419 return 0;
2420 }
2421
2422 int Bimage::pack_transform(unsigned char* data, FourierType tf)
2423 {
2424 return pack_transform(-1, data, tf);
2425 }
2426
2427 int Bimage::pack_transform(int img_select, unsigned char* data, FourierType tf)
2428 {
2429 if ( tf <= Standard ) {
2430 cerr << "Error: The transform is not in the correct format to unpack!" << endl;
2431 exit(-1);
2432 }
2433
2434 if ( verbose & VERB_PROCESS )
2435 cout << "Packing Fourier transform: " << tf << endl << endl;
2436
2437 long i, xx, yy, zz, nn, hx, hy, hz;
2438 long xstore = x, ox(0), oy(0), oz(0);
2439 long elsize = c*data_type_size();
2440
2441 long nmin = (img_select >= 0)? img_select: 0;
2442 long nmax = (img_select >= 0)? img_select: n - 1;
2443
2444 switch ( tf ) {
2445 case Centered:
2446 ox = x/2;
2447 oy = y/2;
2448 oz = z/2;
2449 break;
2450 case Hermitian:
2451 xstore = x/2 + 1;
2452 break;
2453 case CentHerm:
2454 oy = y/2;
2455 oz = z/2;
2456 xstore = x/2 + 1;
2457 break;
2458 default: break;
2459 }
2460
2461 if ( verbose & VERB_DEBUG )
2462 cout << "DEBUG Bimage::pack_transform: Element size = " << elsize << endl;
2463
2464 // cout << "xstore = " << xstore << endl;
2465
2466 // Transfer the data
2467 for ( nn=nmin; nn<=nmax; nn++ ) {
2468 for ( hz=0; hz<z; hz++ ) {
2469 zz = (hz>=oz)? hz - oz: z + hz - oz;
2470 for ( hy=0; hy<y; hy++ ) {
2471 yy = (hy>=oy)? hy - oy: y + hy - oy;
2472 for ( hx=0; hx<xstore; hx++, data+=elsize ) {
2473 xx = (hx>=ox)? hx - ox: x + hx - ox;
2474 i = index(xx, yy, zz, nn);
2475 memcpy(data, data_pointer() + i*elsize, elsize);
2476 }
2477 }
2478 }
2479 }
2480
2481 return 0;
2482 }
2483
2484
2489 int Bimage::information()
2490 {
2491 tm* t = get_localtime();
2492 cout << "Time: " << t->tm_year+1900 << "-" << t->tm_mon+1
2493 << "-" << t->tm_mday << " " << t->tm_hour << ":" << t->tm_min << ":" << t->tm_sec << endl;
2494 // if ( usr.length() ) cout << "User: " << usr << endl;
2495 if ( metadata.exists("user") ) cout << "User: " << metadata["user"] << endl;
2496 cout << "Data offset: " << offset << endl;
2497 cout << "Number of images: " << n << endl;
2498 cout << "Dimensions: " << x << " " << y << " " << z << " voxels" << endl;
2499 cout << "Page dimensions: " << px << " " << py << " " << pz << " voxels" << endl;
2500 cout << "Channels: " << c << endl;
2501 Bstring datatype_string = data_type_string();
2502 cout << "Data type: " << datatype_string <<
2503 " (size = " << data_type_size() << ")" << endl;
2504 if ( fouriertype ) {
2505 cout << "Transform: ";
2506 switch ( fouriertype ) {
2507 case Standard: cout << "Standard" << endl; break;
2508 case Centered: cout << "Centered" << endl; break;
2509 case Hermitian: cout << "Hermitian" << endl; break;
2510 case CentHerm: cout << "Centered hermitian" << endl; break;
2511 default: break;
2512 }
2513 }
2514 Bstring compoundtype_string = compound_type_string();
2515 cout << "Compound type: " << compoundtype_string << endl;
2516 /* cout << "Compound type: ";
2517 switch ( compoundtype ) {
2518 case TSimple: cout << "Simple" << endl; break;
2519 case TComplex: cout << "Complex" << endl; break;
2520 case TVector3: cout << "Vector3" << endl; break;
2521 case TView: cout << "View" << endl; break;
2522 case TRGB: cout << "RGB" << endl; break;
2523 case TRGBA: cout << "RGBA" << endl; break;
2524 case TCMYK: cout << "CMYK" << endl; break;
2525 default: cout << "unknown" << endl; break;
2526 }
2527 */
2528 Vector3<double> u(image->sampling());
2529 cout << "Voxel units/sampling: " << u[0] << " " << u[1] << " " << u[2] << endl;
2530 cout << "Min, max, ave, std: " <<
2531 min << " " << max << " " << avg << " " << std << endl;
2532
2533 cout << "Text label: (length = " << label().length() << ")" << endl;
2534 cout << label() << endl;
2535
2536 UnitCell uc = unit_cell();
2537 Matrix3 frac_mat;
2538 if ( space_group() > 0 ) {
2539 frac_mat = uc.skew_matrix();
2540 cout.setf( ios::fixed, ios::floatfield );
2541 cout << "Unit cell dimensions: " << setprecision(2) <<
2542 uc.a() << " " << uc.b() << " " << uc.c() << endl;
2543 cout << "Unit cell angles: " <<
2544 uc.alpha()*180/M_PI << " " << uc.beta()*180/M_PI << " " << uc.gamma()*180/M_PI << endl;
2545 cout << "Fractionalization matrix: " << setprecision(5) <<
2546 endl << frac_mat;
2547 // cout << "Fractional translation: " <<
2548 // frac_mat[9] << " " << frac_mat[10] << " " << frac_mat[11] << endl;
2549 cout << "Space group: " << space_group() << endl;
2550 }
2551
2552 if ( (symmetry()).length() )
2553 cout << "Symmetry label: " << symmetry() << endl;
2554
2555 cout << endl;
2556
2557 return 0;
2558 }
2559
2564 int Bimage::subimage_information()
2565 {
2566 long nn;
2567
2568 cout << "\nImage\tMin\tMax\tAvg\tStd\tBkg" << endl;
2569 for ( nn=0; nn<n; nn++ )
2570 cout << nn+1 << tab << setprecision(4) <<
2571 image[nn].minimum() << tab <<
2572 image[nn].maximum() << tab <<
2573 image[nn].average() << tab <<
2574 image[nn].standard_deviation() << tab <<
2575 image[nn].background() << endl;
2576
2577 cout << endl;
2578
2579 cout << "Image\tMag\tOrigin\t\t\tView" << endl;
2580 for ( nn=0; nn<n; nn++ )
2581 cout << nn+1 << tab << setprecision(4) <<
2582 image[nn].magnification() << tab << setprecision(2) <<
2583 image[nn].origin() << tab << setprecision(4) <<
2584 image[nn].view().vector3() << tab <<
2585 image[nn].view().angle()*180.0/M_PI << endl;
2586
2587 cout << endl;
2588
2589 // cout << "metadata type = " << metadata.type() << endl;
2590
2591 // cout << metadata << endl;
2592
2593 return 0;
2594 }
2595
2600 int Bimage::moments(long max_order)
2601 {
2602 long nn;
2603
2604 for ( nn=0; nn<n; ++nn ) moments(max_order, nn);
2605
2606 cout << endl;
2607
2608 return 0;
2609 }
2610
2617 int Bimage::moments(long max_order, long nn)
2618 {
2619 if ( max_order < 2 ) max_order = 2;
2620 if ( max_order > 20 ) max_order = 20;
2621
2622 cout << "Moments for image " << nn << ":" << endl;
2623
2624 long i, j, k, ds(image_size());
2625 double v, vc, cm[max_order], m[max_order];
2626
2627 for ( k=0; k<max_order; ++k ) cm[k] = m[k] = 0;
2628
2629 for ( i=0, j=nn*ds; i<ds; ++i, ++j ) {
2630 v = (*this)[j];
2631 vc = 1;
2632 for ( k=0; k<max_order; ++k ) {
2633 vc *= v;
2634 m[k] += vc;
2635 }
2636 }
2637
2638 for ( k=0; k<max_order; ++k ) m[k] /= ds;
2639
2640 for ( i=0, j=nn*ds; i<ds; ++i, ++j ) {
2641 v = (*this)[j] - m[0];
2642 vc = 1;
2643 for ( k=0; k<max_order; ++k ) {
2644 vc *= v;
2645 cm[k] += vc;
2646 }
2647 }
2648
2649 for ( k=0; k<max_order; ++k ) cm[k] /= ds;
2650
2651 v = sqrt(cm[1]); // StDev
2652 vc = 1;
2653
2654 cout << "Order\tMoment\tCentral\tPearson" << endl;
2655 for ( k=0; k<max_order; ++k ) {
2656 vc *= v;
2657 cout << k+1 << tab << m[k] << tab << cm[k] << tab << cm[k]/vc << endl;
2658 }
2659
2660 if ( max_order > 2) cout << "Skewness = " << cm[2]/(cm[1]*sqrt(cm[1])) << endl;
2661 if ( max_order > 3) cout << "Kurtosis = " << cm[3]/(cm[1]*cm[1]) - 3 << endl;
2662 cout << endl;
2663
2664 return 0;
2665 }
2666
2671 void Bimage::get(Bstring tag)
2672 {
2673 if ( tag == "size" ) cout << size() << endl;
2674 else if ( tag == "channels" ) cout << c << endl;
2675 else if ( tag == "x" ) cout << x << endl;
2676 else if ( tag == "y" ) cout << y << endl;
2677 else if ( tag == "z" ) cout << z << endl;
2678 else if ( tag == "images" ) cout << n << endl;
2679 else if ( tag == "sampling" || tag == "pixelsize" ) cout << sampling() << endl;
2680 else if ( tag == "origin" ) cout << image->origin() << endl;
2681 else if ( tag == "view" ) cout << image->view() << endl;
2682 else if ( tag == "min" ) cout << min << endl;
2683 else if ( tag == "max" ) cout << max << endl;
2684 else if ( tag == "avg" ) cout << avg << endl;
2685 else if ( tag == "std" ) cout << std << endl;
2686 else if ( tag == "stat" ) cout << min << tab << max << tab << avg << tab << std << endl;
2687 else if ( tag == "text" ) cout << label() << endl;
2688 else if ( tag == "json" ) cout << metadata << endl;
2689 }
2690
2695 Bimage* Bimage::copy()
2696 {
2697 long j;
2698 Bimage* img = copy_header();
2699 if ( !img ) {
2700 cerr << "Error: Bimage:copy failed!" << endl;
2701 return img;
2702 }
2703
2704 // if ( verbose & VERB_DEBUG )
2705 // cout << "DEBUG Bimage::copy: alloc_size=" << alloc_size() << " data_size=" << data_size() << endl;
2706
2707 img->data_alloc();
2708 for ( j=0; j<img->alloc_size(); j++ ) img->d.uc[j] = d.uc[j];
2709
2710 if ( verbose & VERB_DEBUG )
2711 cout << "DEBUG Bimage::copy: done" << endl;
2712
2713 return img;
2714 }
2715
2721 Bimage* Bimage::copy(long nu_nimg)
2722 {
2723 if ( nu_nimg < 1 ) return copy();
2724
2725 long j;
2726 Bimage* img = copy_header(nu_nimg);
2727 if ( !img ) {
2728 cerr << "Error: Bimage:copy failed!" << endl;
2729 return img;
2730 }
2731
2732 // if ( verbose & VERB_DEBUG )
2733 // cout << "DEBUG Bimage::copy: alloc_size=" << alloc_size() << " data_size=" << data_size() << endl;
2734
2735 for ( j=0; j<n && j<img->n; j++ ) img->image[j] = image[j];
2736 for ( ; j<img->n; j++ ) img->image[j] = image[0];
2737
2738 img->data_alloc();
2739 for ( j=0; j<alloc_size() && j<img->alloc_size(); j++ ) img->d.uc[j] = d.uc[j];
2740
2741 if ( verbose & VERB_DEBUG )
2742 cout << "DEBUG Bimage::copy: done" << endl;
2743
2744 return img;
2745 }
2746
2747
2758 Bimage* Bimage::copy_header(long nu_nimg)
2759 {
2760 long j;
2761
2762 // Allocate memory for the image parameter structure
2763 Bimage* img = new Bimage;
2764 if ( !img ) return img;
2765
2766 img->offset = offset;
2767
2768 img->size(x, y, z);
2769 img->channels(c);
2770 img->data_type(datatype);
2771 img->compound_type(compoundtype);
2772 img->page_size(px, py, pz);
2773 img->fourier_type(fouriertype);
2774
2775 // Copy all strings
2776 img->id = id;
2777
2778 // Statistics
2779 img->minimum(min);
2780 img->maximum(max);
2781 img->average(avg);
2782 img->standard_deviation(std);
2783 img->show_minimum(smin);
2784 img->show_maximum(smax);
2785 img->show_image(sn);
2786 img->show_slice(sz);
2787 img->show_scale(ss);
2788
2789 if ( verbose & VERB_DEBUG )
2790 cout << "DEBUG Bimage::copy_header: New image header copied" << endl;
2791
2792 // Copy metadata
2793 img->metadata = metadata;
2794 // cout << "copy_header:" << endl << img->metadata << endl;
2795
2796 // Create and copy new sub-images
2797 if ( nu_nimg < 1 ) nu_nimg = n;
2798 img->images(nu_nimg);
2799
2800 img->unit_cell(ucell);
2801
2802 if ( verbose & VERB_DEBUG )
2803 cout << "DEBUG Bimage::copy_header: New number of images = " << img->n << endl;
2804
2805 if ( img->n == n )
2806 for ( j=0; j<img->n; j++ ) img->image[j] = image[j];
2807 else
2808 for ( j=0; j<img->n; j++ ) img->image[j] = image[0];
2809
2810 img->data_size();
2811
2812 if ( verbose & VERB_DEBUG )
2813 cout << "DEBUG Bimage::copy_header: Units = " << img->sampling() << endl;
2814
2815 return img;
2816 }
2817
2818
2819
2828 int Bimage::replace(Bimage* img)
2829 {
2830 long j;
2831
2832 for ( j=0; j<datasize; j++ ) set(j, (*img)[j]);
2833
2834 return 0;
2835 }
2836
2847 int Bimage::replace(long nn, Bimage* img, long nr)
2848 {
2849 long i, j, k, imgsize(x*y*z*c);
2850
2851 image[nn] = img->image[nr];
2852
2853 for ( i=nn*imgsize, j=nr*imgsize, k=0; k<imgsize; ++i, ++j, ++k ) set(i, (*img)[j]);
2854
2855 return 0;
2856 }
2857
2869 int Bimage::replace(long nn, Bimage* img, long nr, double fill)
2870 {
2871 long imgsize(x*y*z*c);
2872 long i, j, xx, yy, zz, cc;
2873
2874 image[nn] = img->image[nr];
2875
2876 for ( j=imgsize*nn, i=imgsize*(nn+1); j<i; j++ ) set(j, fill);
2877
2878 for ( zz=0; zz<z && zz<img->z; zz++ ) {
2879 for ( yy=0; yy<y && yy<img->y; yy++ ) {
2880 for ( xx=0; xx<x && xx<img->x; xx++ ) {
2881 i = img->index(0, xx, yy, zz, nr);
2882 j = index(0, xx, yy, zz, nn);
2883 for ( cc=0; cc<c; cc++, i++, j++ ) set(j, (*img)[i]);
2884 }
2885 }
2886 }
2887
2888 return 0;
2889 }
2890
2897 long Bimage::kernel_max(long idx, long ksize)
2898 {
2899 long xx, yy, zz, nn(idx/(x*y*z));
2900 long i, ihi(idx);
2901 double max_val(-1e30);
2902
2903 //calculate the bounds on the kernel
2904 Vector3<long> lo = kernel_low(idx, ksize);
2905 Vector3<long> hi = kernel_high(idx, ksize);
2906
2907 // Loop through the kernel and check neighbors
2908 for ( zz=lo[2]; zz<=hi[2]; zz++ ) {
2909 for ( yy=lo[1]; yy<=hi[1]; yy++ ) {
2910 for ( xx=lo[0]; xx<=hi[0]; xx++ ) {
2911 i = index(0,xx,yy,zz,nn);
2912 if ( max_val < (*this)[i] ) {
2913 max_val = (*this)[i];
2914 ihi = i;
2915 }
2916 }
2917 }
2918 }
2919
2920 return ihi;
2921 }
2922
2929 long Bimage::kernel_max_neigbor(long idx, long ksize)
2930 {
2931 long xx, yy, zz, nn(idx/(x*y*z));
2932 long i, ihi(idx);
2933 double max_val(-1e30);
2934
2935 //calculate the bounds on the kernel
2936 Vector3<long> lo = kernel_low(idx, ksize);
2937 Vector3<long> hi = kernel_high(idx, ksize);
2938
2939 // Loop through the kernel and check neighbors
2940 for ( zz=lo[2]; zz<=hi[2]; zz++ ) {
2941 for ( yy=lo[1]; yy<=hi[1]; yy++ ) {
2942 for ( xx=lo[0]; xx<=hi[0]; xx++ ) {
2943 i = index(0,xx,yy,zz,nn);
2944 if ( max_val < (*this)[i] ) {
2945 if ( i != idx ) {
2946 max_val = (*this)[i];
2947 ihi = i;
2948 }
2949 }
2950 }
2951 }
2952 }
2953
2954 return ihi;
2955 }
2956
2963 long Bimage::kernel_max_wrap(long idx, long ksize)
2964 {
2965 long xx, yy, zz, ix, iy, iz, nn(idx/(x*y*z));
2966 long i, ihi(idx);
2967 double max_val(-1e30);
2968
2969 //calculate the bounds on the kernel
2970 Vector3<long> lo(coordinates(idx)-ksize);
2971 Vector3<long> hi(coordinates(idx)+ksize);
2972
2973 // Loop through the kernel and check neighbors
2974 for ( zz=lo[2]; zz<=hi[2]; zz++ ) {
2975 iz = zz;
2976 while ( iz < 0 ) iz += z;
2977 while ( iz >= z ) iz -= z;
2978 for ( yy=lo[1]; yy<=hi[1]; yy++ ) {
2979 iy = yy;
2980 while ( iy < 0 ) iy += y;
2981 while ( iy >= y ) iy -= y;
2982 for ( xx=lo[0]; xx<=hi[0]; xx++ ) {
2983 ix = xx;
2984 while ( ix < 0 ) ix += x;
2985 while ( ix >= x ) ix -= x;
2986 i = index(0,ix,iy,iz,nn);
2987 if ( max_val < (*this)[i] ) {
2988 max_val = (*this)[i];
2989 ihi = i;
2990 }
2991 }
2992 }
2993 }
2994
2995 return ihi;
2996 }
2997
3010 double Bimage::density(long nn, Vector3<double> coord, double radius, double& sigma)
3011 {
3012 long i, xx, yy, zz;
3013 double x2, y2, z2, rad2(radius*radius);
3014 double density(0), dist2, v, w, sum(0), sum2(0), sumw(0), fac(-9/rad2);
3015
3016 Vector3<double> lo = coord - radius;
3017 Vector3<double> hi = coord + radius;
3018 lo = lo.max(0);
3019 if ( hi[0] >= x ) hi[0] = x - 1;
3020 if ( hi[1] >= y ) hi[1] = y - 1;
3021 if ( hi[2] >= z ) hi[2] = z - 1;
3022
3023 for ( zz=(long)lo[2]; zz<=hi[2]; zz++ ) {
3024 z2 = zz - coord[2];
3025 z2 *= z2;
3026 for ( yy=(long)lo[1]; yy<=hi[1]; yy++ ) {
3027 y2 = yy - coord[1];
3028 y2 *= y2;
3029 for ( xx=(long)lo[0]; xx<=hi[0]; xx++ ) {
3030 x2 = xx - coord[0];
3031 x2 *= x2;
3032 dist2 = x2 + y2 + z2;
3033 if ( dist2 <= rad2 ) {
3034 i = index(0, xx, yy, zz, nn);
3035 // if ( (*this)[i] > average() ) {
3036 w = exp(fac*dist2);
3037 v = (*this)[i];
3038 sum += w*v;
3039 sum2 += w*v*v;
3040 sumw += w;
3041 // }
3042 }
3043 }
3044 }
3045 }
3046
3047 if ( sumw ) {
3048 density = sum/sumw;
3049 sigma = sum2/sumw - density*density;
3050 if ( sigma > 0 ) sigma = sqrt(sigma);
3051 else sigma = 0;
3052 }
3053
3054 return density;
3055 }
3056
3069 double Bimage::relative_density(Bimage* pmask)
3070 {
3071 int t;
3072 long i, np(0), nr(0), nb(0);
3073 double dp(0), dr(0), db(0);
3074
3075 for ( i=0; i<datasize; i++ ) {
3076 t = (int) ((*pmask)[i] + 0.5);
3077 if ( t == 1 ) {
3078 dp += (*this)[i]; // Region of interest
3079 np++;
3080 } else if ( t == 2 ) {
3081 dr += (*this)[i]; // Reference region
3082 nr++;
3083 } else if ( t == 3 ) {
3084 db += (*this)[i]; // Background region
3085 nb++;
3086 }
3087 }
3088
3089 if ( np ) dp /= np;
3090 if ( nr ) dr /= nr;
3091 if ( nb ) db /= nb;
3092
3093 if ( dr - db ) dp = (dp - db)/(dr - db);
3094 else if ( dr ) dp /= dr;
3095
3096 return dp;
3097 }
3098
3099
3108 void Bimage::invert()
3109 {
3110 long j, ds;
3111
3112 switch ( datatype ) {
3113 case Bit: ds = (px/8)*y*z*n; for ( j=0; j<ds; j++ ) d.uc[j] = ~d.uc[j]; break;
3114 case UCharacter: case UShort: case UInteger: case ULong:
3115 for ( j=0; j<datasize; j++ ) set(j, dtmax - (*this)[j]); break;
3116 default:
3117 for ( j=0; j<datasize; j++ ) set(j, -(*this)[j]); break;
3118 }
3119
3120 statistics();
3121 }
3122
3134 void Bimage::reslice(Bstring order)
3135 {
3136 if ( !d.uc ) return;
3137
3138 long i, j;
3139 Vector3<long> nusize, coor, nucoor;
3140 Vector3<long> sign(1,1,1), ind(0,1,2);
3141 Vector3<double> u(image->sampling()), un;
3142
3143 order.lower();
3144
3145 if ( !order.contains("x") || !order.contains("y") || !order.contains("z") ) {
3146 cerr << "Error: Reslice order specification not correct: " << order << endl << endl;
3147 return;
3148 }
3149
3150 if ( verbose & VERB_DEBUG ) {
3151 cout << "DEBUG Bimage::reslice: size" << tab << size() << endl;
3152 cout << "DEBUG Bimage::reslice:";
3153 }
3154
3155 j = 0;
3156 for ( i=0; i<order.length(); i++ ) {
3157 if ( order[i] == 'x' ) {
3158 ind[j] = 0; nusize[j] = x; un[j] = u[0];
3159 j++;
3160 }
3161 if ( order[i] == 'y' ) {
3162 ind[j] = 1; nusize[j] = y; un[j] = u[1];
3163 j++;
3164 }
3165 if ( order[i] == 'z' ) {
3166 ind[j] = 2; nusize[j] = z; un[j] = u[2];
3167 j++;
3168 }
3169 if ( j < 3 ) {
3170 if ( order[i] == '-' ) sign[j] = -1;
3171 else sign[j] = 1;
3172 }
3173 if ( verbose & VERB_DEBUG )
3174 cout << tab << order[i] << " " << sign[j];
3175 }
3176
3177 if ( verbose & VERB_DEBUG )
3178 cout << endl << "DEBUG Bimage::reslice: nusize" << tab << nusize << endl;
3179
3180 long elementsize(c*data_type_size());
3181 long ds(x*y*z*n);
3182 unsigned char* nudata = new unsigned char[alloc_size()];
3183 for ( i=0; i<alloc_size(); i++ ) nudata[i] = 0;
3184
3185 if ( verbose & VERB_DEBUG )
3186 cout << "DEBUG Bimage::reslice: elementsize=" << elementsize << " datasize=" << ds << endl;
3187
3188 long nn, xx, yy, zz;
3189 Vector3<double> ori, nuori;
3190
3191 for ( i=nn=0; nn<n; nn++ ) {
3192 ori = image[nn].origin();
3193 for ( j=0; j<3; j++ ) {
3194 nuori[j] = ori[ind[j]];
3195 if ( sign[j] < 0 ) nuori[j] = nusize[j] - 1 - nuori[j];
3196 }
3197 image[nn].origin(nuori);
3198 for ( zz=0; zz<z; zz++ ) {
3199 coor[2] = zz;
3200 for ( yy=0; yy<y; yy++ ) {
3201 coor[1] = yy;
3202 for ( xx=0; xx<x; xx++, i++ ) {
3203 coor[0] = xx;
3204 for ( j=0; j<3; j++ ) {
3205 nucoor[j] = coor[ind[j]];
3206 if ( sign[j] < 0 ) nucoor[j] = nusize[j] - 1 - nucoor[j];
3207 }
3208 j = ((nn*nusize[2] + nucoor[2])*nusize[1] + nucoor[1])*nusize[0] + nucoor[0];
3209 if ( datatype == Bit ) {
3210 if ( (*this)[i] ) nudata[j/8] |= 0x80 >> ((i/x)*px + i%x)%8;
3211 } else {
3212 memcpy(nudata+j*elementsize, d.uc+i*elementsize, elementsize);
3213 // for ( cc=0, ic=i*c, jc=j*c; cc<c; cc++, ic++, jc++ ) nudata[jc] = (*p)[ic];
3214 }
3215 }
3216 }
3217 }
3218 }
3219
3220 size(nusize);
3221 sampling(un);
3222 data_assign(nudata);
3223
3224 if ( verbose & VERB_DEBUG )
3225 cout << "DEBUG Bimage::reslice: alloc_size=" << alloc_size() << endl;
3226
3227 return;
3228 }
3229
3234 void Bimage::add(double v)
3235 {
3236 double v1;
3237
3238 for ( long j=0; j<datasize; j++ ) {
3239 v1 = (*this)[j] + v;
3240 set(j, v1);
3241 }
3242
3243 statistics();
3244 }
3245
3250 void Bimage::multiply(double v)
3251 {
3252 long j, nn;
3253 double v1;
3254
3255 for ( j=0; j<datasize; j++ ) {
3256 v1 = (*this)[j] * v;
3257 set(j, v1);
3258 }
3259
3260 for ( nn=0; nn<n; nn++ )
3261 image[nn].background(background(nn) * v);
3262
3263 statistics();
3264 }
3265
3271 void Bimage::multiply(long nn, double v)
3272 {
3273 long i, j, imgsize(c*x*y*z);
3274 double v1;
3275
3276 for ( i=0, j=nn*imgsize; i<imgsize; i++, j++ ) {
3277 v1 = (*this)[j] * v;
3278 set(j, v1);
3279 }
3280
3281 statistics();
3282 }
3283
3288 void Bimage::power(double v)
3289 {
3290 double v1;
3291
3292 for ( long j=0; j<datasize; j++ ) {
3293 v1 = pow((*this)[j], v);
3294 set(j, v1);
3295 }
3296
3297 statistics();
3298 }
3299
3303 void Bimage::sum_images()
3304 {
3305 if ( n < 2 ) return;
3306
3307 long i, j, nn, img_size(c*x*y*z);
3308
3309 float* nudata = new float[img_size];
3310
3311 for ( j=0; j<img_size; j++ ) nudata[j] = 0;
3312
3313 for ( nn=i=0; nn<n; nn++ )
3314 for ( j=0; j<img_size; j++, i++ ) nudata[j] += (*this)[i];
3315
3316 n = 1;
3317 Bsub_image* nusub = new Bsub_image[1];
3318 nusub[0] = image[0];
3319 delete[] image;
3320 image = nusub;
3321
3322 data_type(Float);
3323 data_assign((unsigned char *) nudata);
3324
3325 statistics();
3326 }
3327
3333 Bimage* Bimage::average_images(bool sd)
3334 {
3335 if ( n < 2 ) return NULL;
3336
3337 Bimage* pavg = new Bimage(Float, TSimple, size(), 1);
3338 pavg->clear();
3339
3340 Bimage* pstd = NULL;
3341 if ( sd ) pstd = pavg->next = pavg->copy();
3342
3343 long i, j, nn, img_size(c*x*y*z);
3344 double v, w(1.0/n);
3345
3346 for ( nn=i=0; nn<n; nn++ )
3347 for ( j=0; j<img_size; j++, i++ ) {
3348 v = (*this)[i];
3349 pavg->add(j, v);
3350 if ( sd ) pstd->add(j, v*v);
3351 }
3352
3353 pavg->multiply(w);
3354
3355 if ( sd ) {
3356 pstd->multiply(w);
3357 for ( j=0; j<img_size; j++ ) {
3358 v = (*pstd)[j] - (*pavg)[j]*(*pavg)[j];
3359 if ( v > 0 ) v = sqrt(v);
3360 else v = 0;
3361 pstd->set(j, v);
3362 }
3363 }
3364
3365 pavg->statistics();
3366 if ( sd ) pstd->statistics();
3367
3368 return pavg;
3369 }
3370
3378 void Bimage::add(Bimage* p)
3379 {
3380 if ( !check_if_same_size(p) ) {
3381 error_show("Bimage::add", __FILE__, __LINE__);
3382 return;
3383 }
3384
3385 long j;
3386 double v1;
3387
3388 for ( j=0; j<datasize; j++ ) {
3389 v1 = (*this)[j] + (*p)[j];
3390 set(j, v1);
3391 }
3392
3393 statistics();
3394 }
3395
3403 void Bimage::subtract(Bimage* p)
3404 {
3405 if ( !check_if_same_size(p) ) {
3406 error_show("Bimage::subtract", __FILE__, __LINE__);
3407 return;
3408 }
3409
3410 double v1;
3411
3412 for ( long j=0; j<datasize; j++ ) {
3413 v1 = (*this)[j] - (*p)[j];
3414 set(j, v1);
3415 }
3416
3417 statistics();
3418 }
3419
3431 void Bimage::add(long nn, Bimage* p)
3432 {
3433 long i, j, imgsize(c*image_size());
3434 double v1;
3435
3436 for ( i=0, j=nn*imgsize; i<imgsize; i++, j++ ) {
3437 v1 = (*this)[j] + (*p)[i];
3438 set(j, v1);
3439 }
3440
3441 statistics();
3442 }
3443
3453 void Bimage::add(Bimage* p, double scale, double shift)
3454 {
3455 if ( !check_if_same_size(p) ) {
3456 error_show("Bimage::add", __FILE__, __LINE__);
3457 return;
3458 }
3459
3460 double v1;
3461
3462 for ( long j=0; j<datasize; j++ ) {
3463 v1 = (*this)[j] + (*p)[j] * scale + shift;
3464 set(j, v1);
3465 }
3466
3467 statistics();
3468 }
3469
3480 void Bimage::add(long nn, Bimage* p, double scale, double shift)
3481 {
3482 long i, j, imgsize(c*image_size());
3483 double v1;
3484
3485 for ( i=0, j=nn*imgsize; i<imgsize; i++, j++ ) {
3486 v1 = (*this)[j] + (*p)[i] * scale + shift;
3487 set(j, v1);
3488 }
3489
3490 statistics();
3491 }
3492
3502 void Bimage::multiply(Bimage* p, double scale, double shift)
3503 {
3504 if ( !check_if_same_size(p) ) {
3505 error_show("Bimage::multiply", __FILE__, __LINE__);
3506 return;
3507 }
3508
3509 double v1;
3510
3511 for ( long j=0; j<datasize; j++ ) {
3512 v1 = (*this)[j] * ((*p)[j] * scale + shift);
3513 set(j, v1);
3514 }
3515
3516 statistics();
3517 }
3518
3527 void Bimage::multiply(long nn, Bimage* p)
3528 {
3529 if ( nn >= n ) return;
3530
3531 long imgsize(x*y*z*c), i(nn*imgsize), j(0), k(0);
3532
3533 if ( p->n == n ) j = i;
3534
3535 for ( k=0; k<imgsize; ++i, ++j, ++k )
3536 set(i, (*this)[i] * (*p)[j]);
3537 }
3538
3547 void Bimage::multiply(Bimage* p)
3548 {
3549 if ( verbose & VERB_PROCESS )
3550 cout << "Multiplying " << n << " sub-images with " << p->n << " sub-images" << endl << endl;
3551
3552 if ( datatype >= Float || p->datatype >= Float )
3553 change_type(Float);
3554
3555 #ifdef HAVE_GCD
3556 dispatch_apply(n, dispatch_get_global_queue(0, 0), ^(size_t nn){
3557 multiply(nn, p);
3558 });
3559 #else
3560 #pragma omp parallel for
3561 for ( long nn=0; nn<n; ++nn )
3562 multiply(nn, p);
3563 #endif
3564
3565 statistics();
3566 }
3567
3579 void Bimage::divide(Bimage* p, double scale, double shift)
3580 {
3581 double minval = p->min*scale + shift;
3582
3583 if ( !check_if_same_size(p) ) {
3584 error_show("Bimage::divide", __FILE__, __LINE__);
3585 return;
3586 }
3587
3588 if ( minval < 0 ) {
3589 cerr << "Error: The scaled and shifted second image must be positive! (min = "
3590 << minval << ")" << endl << endl;
3591 return;
3592 }
3593
3594 long j;
3595 double div;
3596 Complex<float> cv;
3597 // if ( minval <= 0 ) minval = p->standard_deviation()/1000;
3598 if ( minval < 1e-10 ) minval = scale;
3599 if ( minval < 1e-10 ) minval = shift;
3600 if ( minval < 1e-10 ) minval = 1e-10;
3601
3602 if ( compound_type() != TComplex ) {
3603 for ( j=0; j<datasize; j++ ) {
3604 div = (*p)[j] * scale + shift;
3605 if ( div < minval ) div = minval;
3606 set(j, (*this)[j]/div);
3607 }
3608 } else {
3609 for ( j=0; j<datasize; j++ ) {
3610 cv = p->complex(j) * scale + shift;
3611 div = cv.power();
3612 if ( div < minval ) div = minval;
3613 cv = cv.conj();
3614 set(j, (p->complex(j)*cv)/div);
3615 }
3616 }
3617
3618 statistics();
3619 }
3620
3632 void Bimage::divide_one(Bimage* p, double scale, double shift)
3633 {
3634 double minval = p->image->minimum()*scale + shift;
3635
3636 if ( minval < 0 ) {
3637 cerr << "Error: The scaled and shifted second image must be positive! (min = "
3638 << minval << ")" << endl << endl;
3639 return;
3640 }
3641
3642 long i, j, nn, imgsize(x*y*z*c);
3643 double div;
3644 Complex<float> cv;
3645 // if ( minval <= 0 ) minval = p->standard_deviation()/1000;
3646 if ( minval < 1e-10 ) minval = scale;
3647 if ( minval < 1e-10 ) minval = shift;
3648 if ( minval < 1e-10 ) minval = 1e-10;
3649
3650 if ( compound_type() != TComplex ) {
3651 for ( i=nn=0; nn<n; nn++ ) {
3652 for ( j=0; j<imgsize; j++, i++ ) {
3653 div = (*p)[j] * scale + shift;
3654 if ( div < minval ) div = minval;
3655 set(i, (*this)[i]/div);
3656 }
3657 }
3658 } else {
3659 imgsize /= 2;
3660 for ( i=nn=0; nn<n; nn++ ) {
3661 for ( j=0; j<imgsize; j++, i++ ) {
3662 cv = p->complex(j) * scale + shift;
3663 div = cv.power();
3664 if ( div < minval ) div = minval;
3665 cv = cv.conj();
3666 set(i, (p->complex(i)*cv)/div);
3667 }
3668 }
3669 }
3670
3671 statistics();
3672 }
3673
3682 void Bimage::inverse(double minval)
3683 {
3684 long j;
3685 double v;
3686 double invminval(0);
3687 if ( minval ) invminval = 1.0/minval;
3688
3689 for ( j=0; j<datasize; j++ ) {
3690 v = (*this)[j];
3691 if ( fabs(v) > minval )
3692 set(j, 1/v);
3693 else if ( v > 0 )
3694 set (j, invminval);
3695 else
3696 set(j, -invminval);
3697 }
3698
3699 statistics();
3700 }
3701
3706 void Bimage::largest(Bimage* p)
3707 {
3708 if ( !check_if_same_size(p) ) {
3709 error_show("Bimage::largest", __FILE__, __LINE__);
3710 return;
3711 }
3712
3713 if ( verbose & VERB_PROCESS )
3714 cout << "Setting to the largest" << endl;
3715
3716 double v1;
3717 for ( long j=0; j<datasize; j++ ) {
3718 v1 = (*p)[j];
3719 if ( (*this)[j] < v1 ) set(j, v1);
3720 }
3721
3722 statistics();
3723 }
3724
3730 void Bimage::smallest(Bimage* p)
3731 {
3732 if ( !check_if_same_size(p) ) {
3733 error_show("Bimage::smallest", __FILE__, __LINE__);
3734 return;
3735 }
3736
3737 if ( verbose & VERB_PROCESS )
3738 cout << "Setting to the smallest" << endl;
3739
3740 double v1;
3741 for ( long j=0; j<datasize; j++ ) {
3742 v1 = (*p)[j];
3743 if ( (*this)[j] > v1 ) set(j, v1);
3744 }
3745
3746 statistics();
3747 }
3748
3759 Bimage* Bimage::operator+(Bimage& p)
3760 {
3761 if ( n != p.n ) {
3762 error_show("Error in Bimage::operator+", __FILE__, __LINE__);
3763 cerr << "Different numbers of sub-images: " << n << " vs " << p.n << endl << endl;
3764 return this;
3765 }
3766
3767 if ( c != p.c ) {
3768 error_show("Error in Bimage::operator+", __FILE__, __LINE__);
3769 cerr << "Different numbers of channels: " << c << " vs " << p.c << endl << endl;
3770 return this;
3771 }
3772
3773 Vector3<long> sz(size().max(p.size()));
3774
3775 long i, j, xx, yy, zz, cc, nn;
3776 long i1, i2, x1, x2, y1, y2, z1, z2;
3777 double v;
3778 double fill((avg + p.avg)/2);
3779
3780 Bimage* pnu = new Bimage(Float, compound_type(), sz, n);
3781 pnu->sampling(sampling());
3782
3783 if ( verbose & VERB_PROCESS ) {
3784 cout << "Summing two images:" << endl;
3785 cout << "New size: " << sz << endl;
3786 }
3787
3788 for ( i=nn=0; nn<n; nn++ ) {
3789 for ( zz=0; zz<pnu->z; zz++ ) {
3790 z1 = z2 = -1;
3791 if ( zz < z ) z1 = zz;
3792 if ( zz < p.z ) z2 = zz;
3793 for ( yy=0; yy<pnu->y; yy++ ) {
3794 y1 = y2 = -1;
3795 if ( z1 > -1 && yy < y ) y1 = yy;
3796 if ( z2 > -1 && yy < p.y ) y2 = yy;
3797 for ( xx=0; xx<pnu->x; xx++ ) {
3798 x1 = x2 = -1;
3799 if ( y1 > -1 && xx < x ) x1 = xx;
3800 if ( y2 > -1 && xx < p.x ) x2 = xx;
3801 for ( cc=0; cc<c; cc++, i++ ) {
3802 j = 0;
3803 v = (*pnu)[i];
3804 if ( x1 > -1 ) {
3805 i1 = index(cc,x1,y1,z1,nn);
3806 v += (*this)[i1];
3807 j++;
3808 }
3809 if ( x2 > -1 ) {
3810 i2 = p.index(cc,x2,y2,z2,nn);
3811 v += p[i2];
3812 j++;
3813 }
3814 if ( j ) v /= j;
3815 else v = fill;
3816 pnu->set(i, v);
3817 }
3818 }
3819 }
3820 }
3821 pnu->image[nn].background(background(nn) + p.background(nn));
3822 }
3823
3824 pnu->statistics();
3825
3826 return pnu;
3827 }
3828
3836 Bplot* Bimage::plot()
3837 {
3838 if ( y*z > 1 ) {
3839 cerr << "Error in plot_from_image: Only one-dimensional images can be converted!" << endl;
3840 bexit(-1);
3841 }
3842
3843 change_type(Float);
3844
3845 long i, j, nn, cc, xx;
3846 long npage(n);
3847 long nrow(x);
3848 long ncol(n*(1 + c));
3849 double dist, ux;
3850 Bstring title(file_name());
3851
3852 Bplot* plot = new Bplot(npage, nrow, ncol);
3853
3854 plot->title(title);
3855
3856 for ( nn=0; nn<npage; nn++ ) {
3857 ux = sampling(nn)[0];
3858 title = file_name().c_str() + Bstring(nn+1, ": %d");
3859 plot->page(nn).title(title);
3860 plot->page(nn).columns(1+c);
3861 plot->page(nn).column(0).number(nn*(1+c));
3862 plot->page(nn).column(0).label("x");
3863 plot->page(nn).column(0).axis(1);
3864 for ( i=1, j=1+nn*(1+c); i<=c; i++, j++ ) {
3865 plot->page(nn).column(i).number(j);
3866 plot->page(nn).column(i).type(2);
3867 plot->page(nn).column(i).label("Value");
3868 plot->page(nn).column(i).axis(3);
3869 }
3870 /* if ( c == 2 ) {
3871 plot->page(nn).column(1).color(1,0,0);
3872 plot->page(nn).column(2).color(0,0,1);
3873 }
3874 if ( c > 2 ) {
3875 plot->page(nn).column(1).color(1,0,0);
3876 plot->page(nn).column(2).color(0,1,0);
3877 plot->page(nn).column(3).color(0,0,1);
3878 }*/
3879 for ( cc=0; cc<c; ++cc ) {
3880 dist = cc*2.0/(c-1);
3881 if ( dist < 1 ) {
3882 plot->page(nn).column(cc+1).color(1 - dist, dist, 0);
3883 } else {
3884 plot->page(nn).column(cc+1).color(0, 2 - dist, dist - 1);
3885 }
3886 }
3887 plot->page(nn).axis(1).min(-image[nn].origin()[0]*ux);
3888 plot->page(nn).axis(1).max((x-1-image[nn].origin()[0])*ux);
3889 plot->page(nn).axis(3).min(minimum());
3890 plot->page(nn).axis(3).max(maximum());
3891 for ( xx=0, i=nrow*nn*(1+c); xx<nrow; xx++, i++ )
3892 (*plot)[i] = (xx - image[nn].origin()[0])*ux;
3893 for ( cc=0; cc<c; cc++ )
3894 for ( xx=0, j=cc+nn*nrow*c; xx<nrow; xx++, i++, j+=c )
3895 (*plot)[i] = (*this)[j];
3896 }
3897
3898 return plot;
3899 }
3900
3901
3902
3903
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
M_PI_2
#define M_PI_2
Definition: utilities.h:62
UnitCell
Definition: UnitCell.h:22
Bimage::replace
int replace(Bimage *img)
Replaces the data with that from the given image.
Definition: Bimage.cpp:2828
Bimage::compatible
bool compatible(Bimage *p)
Check if this image has the same number of channels and data type as another.
Definition: Bimage.cpp:623
Bimage::kernel_max_neigbor
long kernel_max_neigbor(long idx, long ksize)
Finds the highest value in a kernel excluding the central voxel.
Definition: Bimage.cpp:2929
TypePointer::si
int * si
Definition: Bimage.h:74
Bimage::copy_header
Bimage * copy_header()
Definition: Bimage.h:650
Bsub_image::view
void view(double x, double y, double z, double a)
Definition: Bimage.h:143
Bimage.h
Header file for image class.
DataType
DataType
Base data type specifier.
Definition: utilities.h:146
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Vector3::length
double length()
Definition: Vector3.h:222
Baxis::min
double min()
Definition: Bplot.h:30
Bimage::add
void add(long j, double v)
Definition: Bimage.h:308
Bimage::information
int information()
Prints out header information for an image.
Definition: Bimage.cpp:2489
RGBA::a
Type a()
Definition: Color.h:203
Bimage::data_type_bits
long data_type_bits() const
Returns the size of the datatype in bits.
Definition: Bimage.cpp:1560
Bsub_image
General sub-image parameter class.
Definition: Bimage.h:88
BVERSION
#define BVERSION
Definition: utilities.h:9
Bimage::slices_to_images
int slices_to_images()
Changes the slices in a 3D image into a set of 2D images.
Definition: Bimage.cpp:2052
TMulti
Definition: Bimage.h:65
Bimage::invert
void invert()
Inverts the data in the image.
Definition: Bimage.cpp:3108
Bplot::title
Bstring & title()
Definition: Bplot.h:189
JSvalue::integer
long & integer()
Definition: json.h:136
RGB::g
Type g()
Definition: Color.h:46
UnitCell::gamma
void gamma(double d)
Definition: UnitCell.h:41
Bimage::data_type_size
long data_type_size() const
Returns the size of the datatype in bytes.
Definition: Bimage.cpp:1585
utilities.h
Header file for general utilities.
Bimage::read_data
unsigned char * read_data(ifstream *fimg, int img_select, int sb, int vax, long pad)
Read image data in a generalized style.
Definition: Bimage.cpp:2188
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bcolumn::label
Bstring & label()
Definition: Bplot.h:63
TypePointer::ui
unsigned int * ui
Definition: Bimage.h:73
TView
Definition: Bimage.h:61
TypePointer::ss
short * ss
Definition: Bimage.h:72
Bsub_image::background
double background()
Definition: Bimage.h:121
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
UnitCell::beta
void beta(double d)
Definition: UnitCell.h:40
RGBA
Definition: Color.h:11
Bimage::set_max
void set_max(double xx, double yy, double zz, long nn, double v)
Sets a value at a given location to neigboring data elements if it is larger.
Definition: Bimage.cpp:1281
Bimage::data_type_string
Bstring data_type_string()
Get the string representation of a datatype.
Definition: Bimage.cpp:1667
TypePointer::sl
long * sl
Definition: Bimage.h:76
Bimage::rgba
RGBA< double > rgba(long j)
Returns a color value at the given index.
Definition: Bimage.cpp:1047
Integer
Definition: utilities.h:154
Bimage::interpolate_wrap
double interpolate_wrap(long cc, double xx, double yy=0, double zz=0, long nn=0) const
Interpolates using a given location with wrapping.
Definition: Bimage.cpp:1502
Bimage::index
long index(long nx, long ny) const
Definition: Bimage.h:383
Bimage::fix_type
void fix_type()
Determines the replacement data type.
Definition: Bimage.cpp:1718
Matrix3
Definition: Matrix3.h:17
Complex::conj
Complex conj()
Definition: Complex.h:106
Bstring::length
long length() const
Definition: Bstring.cpp:263
Bimage::delete_images
long delete_images(Bstring list, int retain=0)
Retains or deletes sub-images from a multi-image structure.
Definition: Bimage.cpp:2134
Bimage::complex
Complex< double > complex(long j)
Returns a complex value at the given index.
Definition: Bimage.cpp:1005
TypePointer::uc
unsigned char * uc
Definition: Bimage.h:69
SCharacter
Definition: utilities.h:150
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
Bimage::check
void check()
Checks an image for reasonable properties.
Definition: Bimage.cpp:389
UnitCell::a
void a(double d)
Definition: UnitCell.h:36
FourierType
FourierType
Fourier transform format specifier.
Definition: Bimage.h:39
Bimage::show_scale
double show_scale()
Definition: Bimage.h:556
Bimage::multiply
void multiply(long j, Complex< double > cv)
Definition: Bimage.h:312
Bcolumn::color
double * color()
Definition: Bplot.h:76
Long
Definition: utilities.h:156
TComplex
Definition: Bimage.h:59
Bimage::zero_fourier_origin
void zero_fourier_origin()
Zeroes the first voxel in each image.
Definition: Bimage.cpp:2011
Bimage::subimage_information
int subimage_information()
Prints out header information for all sub-images.
Definition: Bimage.cpp:2564
Bpage::column
Bcolumn & column(long i)
Definition: Bplot.h:110
Bimage::pack_transform
int pack_transform(unsigned char *data, FourierType tf)
Definition: Bimage.cpp:2422
Bimage::Bimage
Bimage()
Initializes an image.
Definition: Bimage.cpp:44
Bimage::operator=
Bimage & operator=(const Bimage &p)
Assigns an image.
Definition: Bimage.cpp:888
JSvalue::real
double & real()
Definition: json.h:143
Bimage::check_if_same_image_size
bool check_if_same_image_size(Bimage *p)
Check if two images are the same size.
Definition: Bimage.cpp:562
Bimage::data_delete
void data_delete()
Deallocates the image data.
Definition: Bimage.cpp:874
Bimage::interpolate
double interpolate(long cc, double xx, double yy=0, double zz=0, long nn=0, double fill=0) const
Interpolates using a given location.
Definition: Bimage.cpp:1392
Bimage::~Bimage
~Bimage()
Image destructor.
Definition: Bimage.cpp:191
Bimage::average_images
void average_images()
Definition: Bimage.h:716
Bimage::check_resolution
void check_resolution(double &resolution)
Checks that the resolution falls within reasonable limits.
Definition: Bimage.cpp:605
TCMYK
Definition: Bimage.h:64
TVector3
Definition: Bimage.h:60
TSimple
Definition: Bimage.h:58
Baxis::max
double max()
Definition: Bplot.h:32
Bimage::data_type_max
double data_type_max()
Get the maximum of a datatype.
Definition: Bimage.cpp:1641
Float
Definition: utilities.h:157
CMYK::m
Type m()
Definition: Color.h:301
RGBA::b
Type b()
Definition: Color.h:202
Vector3::max
Type max()
Definition: Vector3.h:175
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::fill_value
TypePointer fill_value(double v)
Definition: Bimage.cpp:1067
Bimage::power
void power(double v)
Calculates the power of an image.
Definition: Bimage.cpp:3288
UInteger
Definition: utilities.h:153
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:256
get_user_name
string get_user_name()
Returns the user name.
Definition: utilities.cpp:85
TypePointer::us
unsigned short * us
Definition: Bimage.h:71
Bstring::contains
bool contains(const Bstring &s)
Definition: Bstring.cpp:584
M_PI
#define M_PI
Definition: utilities.h:59
JSvalue::array_real
vector< double > array_real()
Definition: json.h:166
TypePointer::f
float * f
Definition: Bimage.h:77
isfinite
bool isfinite(complex< T > &value)
TypePointer::sc
signed char * sc
Definition: Bimage.h:70
Bimage::maximum_included_radius
double maximum_included_radius()
Returns the radius of the enclosed sphere or circle.
Definition: Bimage.cpp:2036
Bimage::maximum
double maximum()
Definition: Bimage.h:535
TypePointer::d
double * d
Definition: Bimage.h:78
CompoundType
CompoundType
Compound data type specifier.
Definition: Bimage.h:57
select_numbers
int select_numbers(Bstring &string, int n, int *numsel)
Converts a string with a selection specification into an integer array.
Definition: utilities.cpp:328
Double
Definition: utilities.h:158
Bimage::sum_images
void sum_images()
Adds all sub-images.
Definition: Bimage.cpp:3303
Bcolumn::number
long number()
Definition: Bplot.h:61
Bimage::statistics
long statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Bimage::cmyk
CMYK< double > cmyk(long j)
Returns a color value at the given index.
Definition: Bimage.cpp:1061
CentHerm
Definition: Bimage.h:44
Bimage::data_assign
unsigned char * data_assign(unsigned char *nudata)
Assign image data.
Definition: Bimage.cpp:852
ULong
Definition: utilities.h:155
vax2ieee
void vax2ieee(unsigned char *v, int sb)
Converts VAX floating point format to IEEE floating point format.
Definition: utilities.cpp:548
Bcolumn::type
long type()
Definition: Bplot.h:66
Standard
Definition: Bimage.h:41
Bimage::check_sampling
void check_sampling()
Checks that the sampling is properly specified.
Definition: Bimage.cpp:586
Bsub_image::FOM
double FOM()
Definition: Bimage.h:151
length
double length(vector< T > v)
Definition: Vector3.h:528
TypePointer::ul
unsigned long * ul
Definition: Bimage.h:75
Bpage::axis
Baxis & axis(long id)
Definition: Bplot.h:117
Bimage::unit_cell
void unit_cell(UnitCell uc)
Definition: Bimage.h:601
UnitCell::b
void b(double d)
Definition: UnitCell.h:37
Bsub_image::Bsub_image
Bsub_image()
Initializes a sub-image.
Definition: Bimage.cpp:24
sb
int sb(0)
Bpage::title
Bstring & title()
Definition: Bplot.h:100
RGB
Definition: Color.h:24
TypePointer
Definition: Bimage.h:68
Bimage::show_maximum
double show_maximum()
Definition: Bimage.h:559
Bimage::meta_data_retain_one_image
void meta_data_retain_one_image(long img_num)
Erases all sub-image records from the meta data except one.
Definition: Bimage.cpp:748
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
JSobject
Definition: json.h:26
Bimage::operator+
Bimage * operator+(Bimage &p)
Adds two images together, adjusting for size difference.
Definition: Bimage.cpp:3759
Bimage::inverse
void inverse(double minval=0)
Calculates the inverse of the image.
Definition: Bimage.cpp:3682
Bsub_image::maximum
double maximum()
Definition: Bimage.h:114
JSvalue
Definition: json.h:53
Bimage::average2D
double average2D(long cc, double xf, double yf, double zf, long nn, double iscale)
Averages in the xy plane when scaling is less than 1.
Definition: Bimage.cpp:1312
View::normalize
double normalize()
Definition: View.h:106
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bimage::channels
long channels()
Definition: Bimage.h:371
Bimage::rgb
RGB< double > rgb(long j)
Returns a color value at the given index.
Definition: Bimage.cpp:1033
JSvalue::end
vector< JSvalue >::iterator end()
Definition: json.h:182
Bsub_image::sampling
void sampling(double x, double y, double z)
Definition: Bimage.h:123
swapbytes
void swapbytes(unsigned char *v, size_t n)
Swaps bytes.
Definition: utilities.cpp:504
Bimage::unpack_transform
int unpack_transform(unsigned char *data, FourierType tf)
Definition: Bimage.cpp:2337
Bstring::c_str
const char * c_str()
Definition: Bstring.h:70
Bimage::get
double get(long nn, long xx, long yy, long zz, long cc=0)
Returns the data value at the given coordinates.
Definition: Bimage.cpp:937
RGB::r
Type r()
Definition: Color.h:45
Bimage::reslice
void reslice(const char *order)
Definition: Bimage.h:709
Bimage::standard_deviation
double standard_deviation()
Definition: Bimage.h:537
Bimage::average
double average()
Definition: Bimage.h:536
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
TRGB
Definition: Bimage.h:62
Bimage::relative_density
double relative_density(Bimage *pmask)
Calculates the relative density in a region defined by a mask.
Definition: Bimage.cpp:3069
Bimage::next
Bimage * next
Definition: Bimage.h:165
Complex
Definition: Complex.h:23
JSvalue::begin
vector< JSvalue >::iterator begin()
Definition: json.h:181
Bimage::show_image
long show_image()
Definition: Bimage.h:552
Bimage::kernel_max_wrap
long kernel_max_wrap(long idx, long ksize)
Finds the highest value in a kernel with wrapping.
Definition: Bimage.cpp:2963
volume
T volume(vector< T > v)
Definition: Vector3.h:545
verbose
int verbose
Bimage::select_images
long select_images(Bstring list)
Definition: Bimage.cpp:2168
UnitCell::alpha
void alpha(double d)
Definition: UnitCell.h:39
UCharacter
Definition: utilities.h:149
Bstring
Definition: Bstring.h:29
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2695
Bimage::images_to_slices
int images_to_slices()
Changes the 2D images to slices in a 3D image.
Definition: Bimage.cpp:2093
Bimage::clear
void clear()
Definition: Bimage.h:697
Bplot::page
Bpage & page(long i)
Definition: Bplot.h:211
Bit
Definition: utilities.h:148
UnitCell::degrees_to_radians
void degrees_to_radians()
Definition: UnitCell.h:54
RGBA::r
Type r()
Definition: Color.h:200
Bsub_image::minimum
double minimum()
Definition: Bimage.h:113
Bimage::values
vector< double > values(long i)
Definition: Bimage.h:284
Bimage::alloc_size
long alloc_size() const
Definition: Bimage.h:252
Bimage::write
int write(Bstring &fn)
Definition: Bimage.cpp:2320
Vector3< long >
UnitCell::skew_matrix
Matrix3 skew_matrix()
Calculates the skew matrix from the unit cell parameters.
Definition: UnitCell.cpp:26
JSvalue::exists
bool exists(string tag)
Definition: json.h:215
Complex::imag
Type imag()
Definition: Complex.h:102
Bstring::lower
Bstring lower()
Definition: Bstring.cpp:308
View::angle
double angle()
Definition: View.h:95
View
Definition: View.h:26
Bimage::largest
void largest(Bimage *p)
Selects the largest of each pixel from two images.
Definition: Bimage.cpp:3706
Bsub_image::magnification
double magnification()
Definition: Bimage.h:149
Bimage::divide_one
void divide_one(Bimage *p, double scale=1, double shift=0)
Divides the first image by the first sub-image of the second.
Definition: Bimage.cpp:3632
Bpage::columns
void columns(long ncol)
Definition: Bplot.h:105
RGBA::g
Type g()
Definition: Color.h:201
JSarray
Definition: json.h:27
Bimage::divide
void divide(Bimage *p, double scale=1, double shift=0)
Divides the first image by the second.
Definition: Bimage.cpp:3579
Bimage::average
double average(long cc, double xf, double yf, double zf, long nn, double iscale)
Averages in 3D when scaling is less than 1.
Definition: Bimage.cpp:1349
CMYK::k
Type k()
Definition: Color.h:303
Bimage::compound_type_string
Bstring compound_type_string()
Get the string representation of a datatype.
Definition: Bimage.cpp:1693
Short
Definition: utilities.h:152
Bimage::check_if_same_size
bool check_if_same_size(Bimage *p)
Check if two images are the same size.
Definition: Bimage.cpp:536
Unknown_Type
Definition: utilities.h:147
Bimage::meta_data_update
void meta_data_update()
Update metadata from the sub-image information.
Definition: Bimage.cpp:648
Bimage::density
double density(long nn, Vector3< double > coord, double radius, double &sigma)
Calculates the density in a sphere around a coordinate in an image.
Definition: Bimage.cpp:3010
Bimage::vector3
Vector3< double > vector3(long j)
Returns a 3-value vector at the given index.
Definition: Bimage.cpp:1019
Complex::power
double power()
Definition: Complex.h:103
Bsub_image::average
double average()
Definition: Bimage.h:115
TRGBA
Definition: Bimage.h:63
Bimage::show_slice
long show_slice()
Definition: Bimage.h:554
Complex::real
Type real()
Definition: Complex.h:101
UShort
Definition: utilities.h:151
Bimage::page_size
Vector3< long > page_size()
Definition: Bimage.h:480
Centered
Definition: Bimage.h:42
Bimage::images
long images()
Definition: Bimage.h:491
JSvalue::size
size_t size()
Definition: json.h:108
Bimage::plot
Bplot * plot()
Converts a one-dimensional image into a plot.
Definition: Bimage.cpp:3836
NoTransform
Definition: Bimage.h:40
Hermitian
Definition: Bimage.h:43
JSvalue::push_back
void push_back(const JSvalue &val)
Definition: json.h:191
Bimage::show_minimum
double show_minimum()
Definition: Bimage.h:558
Bimage::kernel_max
long kernel_max(long idx, long ksize)
Finds the highest value in a kernel.
Definition: Bimage.cpp:2897
Bimage::subtract
void subtract(Bimage *p)
Subtracts another image from an image.
Definition: Bimage.cpp:3403
Bimage::background
double background(long nn)
Definition: Bimage.h:542
Bsub_image::select
long select()
Definition: Bimage.h:153
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
Bimage::combine_channels
void combine_channels(long nc)
The channels are composed from individual images.
Definition: Bimage.cpp:1965
Bimage::split_channels
void split_channels()
The channels are split into individual images.
Definition: Bimage.cpp:1924
Bimage::minimum
double minimum()
Definition: Bimage.h:534
Bsub_image::standard_deviation
double standard_deviation()
Definition: Bimage.h:116
bexit
int bexit(int value)
Exit function for cleanup and debugging.
Definition: utilities.cpp:273
TWOPI
#define TWOPI
Definition: utilities.h:68
CMYK
Definition: Color.h:12
Bimage::update_from_meta_data
void update_from_meta_data()
Update sub-image information from the metadata.
Definition: Bimage.cpp:702
RGB::b
Type b()
Definition: Color.h:47
Bimage::operator[]
JSvalue & operator[](string tag)
Definition: Bimage.h:220
Bimage::data_type_min
double data_type_min()
Get the minimum of a datatype.
Definition: Bimage.cpp:1611
Bimage::data_size
long data_size()
Definition: Bimage.h:255
Bimage::fourier_type
FourierType fourier_type()
Definition: Bimage.h:367
Bimage::moments
int moments(long max_order)
Prints out moments for all sub-images.
Definition: Bimage.cpp:2600
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
UnitCell::c
void c(double d)
Definition: UnitCell.h:38
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bcolumn::axis
long axis()
Definition: Bplot.h:68
Bimage::smallest
void smallest(Bimage *p)
Selects the smallest of each pixel from two images.
Definition: Bimage.cpp:3730
Bplot
Definition: Bplot.h:146
CMYK::c
Type c()
Definition: Color.h:300