| Bsoft 2.0.5 Bernard's software package

Bimage_mask.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "utilities.h"
11
12 // Declaration of global variables
13 extern int verbose; // Level of output to the screen
14
26 long Bimage::mask(Bimage* pmask, double fill)
27 {
28 long i, j, cc, ds(x*y*z*n);
29
30 for ( i=j=0; i<ds; i++ )
31 for ( cc=0; cc<c; cc++, j++ )
32 if ( (*pmask)[i] < 0.5 ) set(j, fill);
33
34 if ( verbose & VERB_DEBUG )
35 cout << "DEBUG Bimage::mask: datasize=" << ds << " type=" << datatype << endl;
36
37 statistics();
38
39 return 0;
40 }
41
42
51 long Bimage::to_mask(double threshold)
52 {
53 if ( compoundtype != TSimple ) {
54 cerr << "Error: Conversion from compound types to mask not supported!" << endl;
55 return 0;
56 }
57
58 if ( datatype == UCharacter && min == 0 && max == 1 ) return 0;
59
60 long j, nm(0);
61 unsigned char* mask = new unsigned char[datasize];
62
63 for ( j=0; j<datasize; j++ )
64 if ( (*this)[j] > threshold ) { mask[j] = 1; nm++; }
65 else mask[j] = 0;
66
67 data_type(UCharacter);
68 compoundtype = TSimple;
69 c = 1;
70 min = 0;
71 max = 1;
72
73 data_assign(mask);
74
75 statistics();
76
77 if ( verbose & VERB_DEBUG )
78 cout << "DEBUG Bimage::to_mask: max=" << max << endl;
79
80 return nm;
81 }
82
93 Bimage* Bimage::mask_by_threshold(double threshold)
94 {
95 if ( datatype == Bit ) return copy();
96
97 long i;
98
99 Bimage* pmask = copy_header();
100 pmask->compound_type(TSimple);
101 pmask->data_type(UCharacter);
102 pmask->data_alloc();
103
104 if ( verbose & VERB_LABEL )
105 cout << "Thresholding to: " << threshold << endl << endl;
106
107 for ( i=0; i<datasize; i++ ) {
108 if ( (*this)[i] >= threshold ) pmask->set(i, 1);
109 else pmask->set(i, 0);
110 }
111
112 pmask->statistics();
113
114 if ( verbose & VERB_DEBUG )
115 cout << "DEBUG Bimage::mask_by_threshold: pmask->max=" << pmask->maximum() << endl;
116
117 return pmask;
118 }
119
129 Bimage* Bimage::mask_by_thresholds(vector<double> threshold)
130 {
131 if ( datatype == Bit ) return copy();
132
133 double v;
134
135 Bimage* pmask = copy_header();
136 pmask->compound_type(TSimple);
137 pmask->data_type(UCharacter);
138 pmask->data_alloc();
139
140 if ( verbose & VERB_LABEL )
141 cout << "Thresholding to: " << threshold << endl << endl;
142
143 for ( long i=0; i<datasize; i++ ) {
144 v = (*this)[i];
145 for ( size_t j=0; j<threshold.size(); j++ )
146 if ( v >= threshold[j] ) pmask->set(i, j+1);
147 }
148
149 pmask->statistics();
150
151 if ( verbose & VERB_DEBUG )
152 cout << "DEBUG Bimage::mask_by_threshold: pmask->max=" << pmask->maximum() << endl;
153
154 return pmask;
155 }
156
165 long Bimage::mask_stats()
166 {
167 if ( max < 1 ) statistics();
168
169 long i, j, neg, sum, psum;
170 long nlev = (long) (max + 1.5);
171 if ( nlev < 2 ) nlev = 2;
172
173 double value, volsum;
174 double voxel_volume(sampling().volume());
175 int* h = new int[nlev];
176
177 for ( i=0; i<nlev; i++ ) h[i] = 0;
178
179 if ( verbose & VERB_DEBUG )
180 cout << "DEBUG Bimage::mask_stats: nlev=" << nlev << endl;
181
182 if ( verbose )
183 cout << "Calculating mask statistics:" << endl;
184
185 for ( i=neg=0; i<datasize; i++ ) {
186 value = (*this)[i];
187 if ( value < 0 ) neg++;
188 else {
189 j = (long) (value + 0.5);
190 h[j]++;
191 }
192 }
193
194 for ( i=1, psum=0; i<nlev; i++ ) psum += h[i];
195 sum = psum + neg + h[0];
196 volsum = psum*voxel_volume;
197
198 cout << "Region\tCount\t%\tVolume(A3)" << endl;
199 if ( neg ) cout << "-\t" << neg << tab << neg*100.0/sum << tab << neg*voxel_volume << endl;
200 for ( i=0; i<nlev; i++ ) if ( h[i] )
201 cout << i << tab << h[i] << tab << h[i]*100.0/sum << tab << h[i]*voxel_volume << endl;
202 cout << endl;
203
204 cout << "Count sum: " << psum << endl;
205 cout << "Volume sum: " << volsum << " A3" << endl << endl;
206
207 delete[] h;
208
209 return psum;
210 }
211
221 long Bimage::mask_invert()
222 {
223 to_mask();
224
225 long i, nm(0);
226
227 if ( verbose & VERB_PROCESS )
228 cout << "Inverting mask" << endl << endl;
229
230 for ( i=0; i<datasize; i++ ) {
231 if ( (*this)[i] > 0.5 ) set(i, 0);
232 else { set(i, 1); nm++; }
233 }
234
235 statistics();
236
237 return nm;
238 }
239
256 long Bimage::mask_combine(Bimage* p, int operation)
257 {
258 to_mask();
259 p->to_mask();
260
261 long i;
262
263 // if ( max < 1 || p->maximum() < 1 ) operation = 2;
264
265 if ( verbose & VERB_DEBUG )
266 cout << "DEBUG Bimage::mask_combine: op=" << operation << endl << endl;
267
268 switch ( operation ) {
269 case 1:
270 for ( i=0; i<datasize; i++ ) d.uc[i] = (d.uc[i] & p->d.uc[i]);
271 break;
272 case 2:
273 for ( i=0; i<datasize; i++ ) d.uc[i] = (d.uc[i] | p->d.uc[i]);
274 break;
275 case 3:
276 for ( i=0; i<datasize; i++ ) d.uc[i] = (d.uc[i] ^ p->d.uc[i]);
277 break;
278 default:
279 for ( i=0; i<datasize; i++ ) d.uc[i] = p->d.uc[i];
280 }
281
282 statistics();
283
284 return 0;
285 }
286
294 Bimage* Bimage::mask_extract(Bimage* pmask)
295 {
296 long i, j, cc, ds(x*y*z*n);
297 Bimage* pnu = copy();
298
299 for ( i=j=0; i<ds; i++ )
300 for ( cc=0; cc<c; cc++, j++ )
301 if ( (*pmask)[i] < 0.5 )
302 pnu->set(j, 0);
303
304 pnu->statistics();
305
306 return pnu;
307 }
308
309 int Bimage::max_in_kernel(long ksize)
310 {
311 long i, j, nn, xx, yy, zz, kx, ky, kz;
312 double v, m;
313
314 Vector3<long> k(ksize, ksize, ksize);
315 k = k.min(size());
316
317 Vector3<long> kh(k/2);
318 Vector3<long> lo, hi;
319
320 Bimage* p = new Bimage(datatype, compoundtype, size(), n);
321
322 for ( i=nn=0; nn<n; nn++ ) {
323 for ( zz=0; zz<z; zz++ ) {
324 lo[2] = (zz > kh[2])? zz - kh[2]: 0;
325 hi[2] = (zz+kh[2] < z)? zz + kh[2]: z - 1;
326 for ( yy=0; yy<y; yy++ ) {
327 lo[1] = (yy > kh[1])? yy - kh[1]: 0;
328 hi[1] = (yy+kh[1] < y)? yy + kh[1]: y - 1;
329 for ( xx=0; xx<x; xx++, i++ ) {
330 lo[0] = (xx > kh[0])? xx - kh[0]: 0;
331 hi[0] = (xx+kh[0] < x)? xx + kh[0]: x - 1;
332 m = (*this)[i];
333 for ( kz=lo[2]; kz<=hi[2]; kz++ ) {
334 for ( ky=lo[1]; ky<=hi[1]; ky++ ) {
335 for ( kx=lo[0]; kx<=hi[0]; kx++ ) {
336 j = index(kx, ky, kz, nn);
337 v = (*this)[j];
338 if ( m < v ) m = v;
339 }
340 }
341 }
342 p->set(i, m);
343 }
344 }
345 }
346 }
347
348 for ( i=0; i<datasize; i++ ) set(i, (*p)[i]);
349
350 delete p;
351
352 statistics();
353
354 return 0;
355 }
356
367 long Bimage::mask_dilate_erode(unsigned char dir)
368 {
369 to_mask();
370
371 long i, j, nn, xx, yy, zz, kx, ky, kz;
372
373 Vector3<long> k(3, 3, 3);
374 k = k.min(size());
375
376 Vector3<long> kh(k/2);
377 Vector3<long> lo, hi;
378
379 unsigned char* mask = new unsigned char[datasize];
380 for ( i=0; i<datasize; i++ ) mask[i] = d.uc[i];
381
382 for ( i=nn=0; nn<n; nn++ ) {
383 for ( zz=0; zz<z; zz++ ) {
384 lo[2] = (zz > kh[2])? zz - kh[2]: 0;
385 hi[2] = (zz+kh[2] < z)? zz + kh[2]: z - 1;
386 for ( yy=0; yy<y; yy++ ) {
387 lo[1] = (yy > kh[1])? yy - kh[1]: 0;
388 hi[1] = (yy+kh[1] < y)? yy + kh[1]: y - 1;
389 for ( xx=0; xx<x; xx++, i++ ) {
390 lo[0] = (xx > kh[0])? xx - kh[0]: 0;
391 hi[0] = (xx+kh[0] < x)? xx + kh[0]: x - 1;
392 if ( mask[i] == dir ) {
393 for ( kz=lo[2]; kz<=hi[2]; kz++ ) {
394 for ( ky=lo[1]; ky<=hi[1]; ky++ ) {
395 for ( kx=lo[0]; kx<=hi[0]; kx++ ) {
396 j = index(kx, ky, kz, nn);
397 set(j, dir);
398 }
399 }
400 }
401 }
402 }
403 }
404 }
405 }
406
407 delete[] mask;
408
409 statistics();
410
411 return (long) (avg*datasize);
412 }
413
424 long Bimage::mask_dilate(long times)
425 {
426 long t, nv(0);
427
428 for ( t=0; t<times; t++ )
429 nv = mask_dilate_erode(1);
430
431 return nv;
432 }
433
444 long Bimage::mask_erode(long times)
445 {
446 long t, nv(0);
447
448 for ( t=0; t<times; t++ )
449 nv = mask_dilate_erode(0);
450
451 return nv;
452 }
453
462 long Bimage::mask_open(int times)
463 {
464 long t, nv(0);
465
466 for ( t=0; t<times; t++ ) {
467 mask_erode(1);
468 nv = mask_dilate(1);
469 }
470
471 return nv;
472 }
473
482 long Bimage::mask_close(int times)
483 {
484 long t, nv(0);
485
486 for ( t=0; t<times; t++ ) {
487 mask_dilate(times);
488 nv = mask_erode(times);
489 }
490
491 return nv;
492 }
493
500 long Bimage::mask_fill(Vector3<long> voxel)
501 {
502 return region_assign(this, index(voxel, 0), 1, 0.5, -1);
503 }
504
514 long Bimage::mask_plane(Vector3<double> origin, Vector3<double> normal)
515 {
516 if ( verbose & VERB_DEBUG )
517 cout << "DEBUG Bimage::mask_plane: normal=" << normal << endl;
518
519 normal.normalize();
520
521 long i, nn, xx, yy, zz, total(0);
522 Vector3<double> point;
523
524 if ( verbose & VERB_PROCESS ) {
525 cout << "Generating a planar mask:" << endl;
526 cout << "Normal: " << normal << endl;
527 cout << "Point on plane: " << origin << endl;
528 }
529
530 for ( i=nn=0; nn<n; nn++ ) {
531 for ( zz=0; zz<z; zz++ ) {
532 point[2] = zz - origin[2];
533 for ( yy=0; yy<y; yy++ ) {
534 point[1] = yy - origin[1];
535 for ( xx=0; xx<x; xx++, i++ ) {
536 point[0] = xx - origin[0];
537 if ( normal.scalar(point) > 0 ) {
538 set(i, 1);
539 total++;
540 } else {
541 set(i, 0);
542 }
543 }
544 }
545 }
546 }
547
548 if ( verbose & VERB_PROCESS )
549 cout << "Number of pixels in mask: " << total << endl << endl;
550
551 return total;
552 }
553
569 long Bimage::mask_rectangle(double length, double width,
570 double rect_angle, int wrap)
571 {
572 // change_type(UCharacter) ;
573
574 if ( verbose & ( VERB_LABEL | VERB_PROCESS ) )
575 cout << "Generating a mask along an axis" << endl;
576
577 if ( verbose & VERB_PROCESS ) {
578 cout << "Length and width: " << length << " x " << width << " pixels" << endl;
579 cout << "Axis angle: " << rect_angle*180.0/M_PI << " degrees" << endl;
580 }
581
582 long i, nn, xx, yy, zz, total(0);
583 double xo, yo, xr, yr;
584 double cos_ang(cos(rect_angle)), sin_ang(sin(rect_angle));
585 double half_length(length/2.0), half_width(width/2.0);
586
587 for ( i=nn=0; nn<n; nn++ ) {
588 for ( zz=0; zz<z; zz++ ) {
589 for ( yy=0; yy<y; yy++ ) {
590 yo = yy - image[nn].origin()[1];
591 if ( wrap ) if ( yo > (y - 1)/2 ) yo -= y;
592 for ( xx=0; xx<x; xx++, i++ ) {
593 xo = xx - image[nn].origin()[0];
594 if ( wrap ) if ( xo > (x - 1)/2 ) xo -= x;
595 xr = xo*cos_ang + yo*sin_ang;
596 yr = -xo*sin_ang + yo*cos_ang;
597 if ( xr >= -half_length && xr <= half_length &&
598 yr >= -half_width && yr <= half_width ) {
599 set(i, 1);
600 total++;
601 } else {
602 set(i, 0);
603 }
604 }
605 }
606 }
607 }
608
609 if ( verbose & VERB_PROCESS )
610 cout << "Number of pixels in mask: " << total << endl << endl;
611
612 return total;
613 }
614
621 long Bimage::mask_symmetrize(Bsymmetry* sym)
622 {
623 long i, j, nn, xx, yy, zz, cc;
624
625 View ref = view_symmetry_reference(sym);
626 Vector3<double> vr(ref.vector3());
627 Vector3<double> v, vt, va;
628 double da, minda;
629
630 long nsym(0);
631 Matrix3* m = symmetry_get_all_matrices(sym, nsym);
632
633 if ( verbose & VERB_PROCESS ) {
634 cout << "Symmetrizing a level mask:" << endl;
635 cout << "Symmetry: " << sym->label << endl << endl;
636 }
637
638 int* mask = new int[data_size()];
639
640 for ( i=nn=0; nn<n; nn++ ) {
641 for ( zz=0; zz<z; zz++ ) {
642 v[2] = zz - image[nn].origin()[2];
643 for ( yy=0; yy<y; yy++ ) {
644 v[1] = yy - image[nn].origin()[1];
645 for ( xx=0; xx<x; xx++ ) {
646 v[0] = xx - image[nn].origin()[0];
647 minda = 1e30;
648 for ( j=0; j<nsym; j++ ) {
649 vt = m[j]*v;
650 da = vt.angle(vr);
651 if ( minda > da ) {
652 minda = da;
653 va = vt;
654 }
655 }
656 va += image[nn].origin();
657 for ( cc=0; cc<c; cc++, i++ )
658 mask[i] = get(nn, va, cc);
659 }
660 }
661 }
662 }
663
664 data_type(Integer);
665
666 data_assign((unsigned char *) mask);
667
668 statistics();
669
670 return 0;
671 }
672
683 Vector3<double> Bimage::mask_fspace_resize(Vector3<long> nusize)
684 {
685 if ( verbose & VERB_DEBUG )
686 cout << "DEBUG Bimage::mask_fspace_resize: size=" << nusize << endl;
687
688 Vector3<double> scale(nusize[0]*1.0L/x, nusize[1]*1.0L/y, nusize[2]*1.0L/z);
689
690 if ( nusize.volume() < 1 ) return scale;
691 if ( nusize == size() ) return scale;
692
693 if ( compoundtype != TSimple ) {
694 cerr << "Error: Bimage::mask_fspace_resize: Only simple numbers supported!" << endl;
695 return scale;
696 }
697
698 long i, j, nn, xx, yy, zz, iy, iz;
699 long xold, yold, zold, zerox, zeroy, zeroz;
700 Vector3<long> hold, h, d;
701 long ds(n*nusize.volume());
702 unsigned char* nudata = new unsigned char[ds];
703
704 hold = (size() - 1)/2;
705 h = (nusize - 1)/2;
706 d = nusize - size();
707
708 if ( verbose & VERB_DEBUG )
709 cout << "DEBUG Bimage::mask_fspace_resize: datasize=" << ds << endl;
710
711 if ( verbose & VERB_FULL )
712 cout << "Changing mask to size: " << nusize << " voxels" << endl << endl;
713
714 for ( j=nn=0; nn<n; nn++ ) {
715 for ( zz=0; zz<nusize[2]; zz++ ) {
716 zold = zz;
717 if ( zz > h[2] ) zold -= d[2];
718 zeroz = 0;
719 if ( zz > hold[2] && zz <= d[2] + hold[2] ) zeroz += 1;
720 iz = (nn*z + zold)*y;
721 for ( yy=0; yy<nusize[1]; yy++ ) {
722 yold = yy;
723 if ( yy > h[1] ) yold -= d[1];
724 zeroy = zeroz;
725 if ( yy > hold[1] && yy <= d[1] + hold[1] ) zeroy += 1;
726 iy = (iz + yold)*x;
727 for ( xx=0; xx<nusize[0]; xx++, j++ ) {
728 xold = xx;
729 if ( xx > h[0] ) xold -= d[0];
730 zerox = zeroy;
731 if ( xx > hold[0] && xx <= d[0] + hold[0] ) zerox += 1;
732 if ( zerox < 1 ) {
733 i = iy + xold;
734 nudata[j] = ((*this)[i] > 0.5);
735 }
736 }
737 }
738 }
739 if ( verbose & VERB_DEBUG )
740 cout << "DEBUG Bimage::mask_fspace_resize: origin[" << n << "]=" << image[nn].origin() << endl;
741
742 }
743
744 data_type(UCharacter);
745 sampling(sampling()/scale);
746 size(nusize);
747 page_size(nusize);
748
749 data_assign((unsigned char *) nudata);
750
751 if ( verbose & VERB_DEBUG )
752 cout << "DEBUG Bimage::mask_fspace_resize: sampling=" << sampling() << endl;
753
754 return scale;
755 }
756
772 vector<double> Bimage::fspace_default_bands(double res_lo, double res_hi)
773 {
774 vector<double> band(6,0);
775
776 /* band[0] = x*image->sampling()[0];
777 band[1] = -1;
778 band[2] = res_lo;
779 band[3] = 1;
780 band[4] = res_hi;
781 band[5] = 0;
782 */
783 band[0] = res_lo;
784 band[1] = 1;
785 band[2] = res_hi;
786 band[3] = -1;
787 band[4] = 0.9*res_hi;
788 band[5] = 0;
789
790 if ( verbose & VERB_DEBUG ) {
791 cout << "DEBUG fspace_default_bands:";
792 for ( auto it=band.begin(); it!=band.end(); ++it )
793 cout << tab << *it;
794 cout << endl;
795 }
796
797 return band;
798 }
799
814 int Bimage::mask_fspace_banded(vector<double>& band)
815 {
816 if ( band.size() < 2 || band[0] < 1 ) return -1;
817
818 change_type(SCharacter);
819 fill(0);
820
821 long i, j, xx, yy, zz, h[3] = {0,0,0};
822 long ix, iy, iz;
823 double sx2, sy2, sz2, s2;
824 double sband[100] = {1e-30, 0};
825 Vector3<double> scale(1.0/real_size());
826
827 // cout << "scale = " << scale << endl;
828
829 if ( verbose & VERB_PROCESS ) {
830 cout << "Generating a reciprocal space banded mask:" << endl;
831 cout << "Pixel size: " << sampling()[0] << endl;
832 cout << "Band\tValue" << endl;
833 }
834
835 // The reciprocal space specification starts with an excluded region, followed
836 // by whatever the band specification is set at.
837 for ( j=0; j<100 && band[j] > 0; j += 2 ) {
838 if ( verbose & VERB_PROCESS )
839 cout << band[j] << tab << band[j+1] << endl;
840 sband[j+2] = 1.0/band[j];
841 sband[j+2] *= sband[j+2];
842 sband[j+3] = band[j+1];
843 }
844 sband[j+2] = 0;
845
846 for ( i=zz=0; zz<z; zz++ ) {
847 iz = zz;
848 if ( zz > (z - 1)/2 ) iz -= z;
849 sz2 = iz*scale[2];
850 sz2 *= sz2;
851 for ( yy=0; yy<y; yy++ ) {
852 iy = yy;
853 if ( yy > (y - 1)/2 ) iy -= y;
854 sy2 = iy*scale[1];
855 sy2 *= sy2;
856 for ( xx=0; xx<x; xx++, i++ ) {
857 ix = xx;
858 if ( xx > (x -1 )/2 ) ix -= x;
859 sx2 = ix*scale[0];
860 sx2 *= sx2;
861 s2 = sx2 + sy2 + sz2;
862 for ( j=0; sband[j] > 0 && s2 > sband[j]; j += 2 ) ;
863 if ( j > 0 ) j -= 2;
864 set(i, sband[j+1]);
865 if ( sband[j+1] < 0 ) h[0]++;
866 else if ( sband[j+1] > 0 ) h[2]++;
867 else h[1]++;
868 }
869 }
870 }
871
872 j = h[0] + h[1] + h[2];
873 if ( verbose & VERB_PROCESS ) {
874 cout << "Mask partitions:" << endl;
875 for ( i=0; i<3; i++ )
876 cout << i-1 << tab << h[i] << tab << h[i]*100.0/j << "%" << endl;
877 cout << endl;
878 }
879
880 statistics();
881
882 return 0;
883 }
884
899 long Bimage::mask_missing_wedge(Vector3<double> ori, double tilt_axis,
900 double tilt_neg, double tilt_pos, double resolution)
901 {
902 change_type(UCharacter);
903 clear();
904
905 if ( verbose & ( VERB_LABEL | VERB_PROCESS ) )
906 cout << "Generating a mask with a missing wedge" << endl;
907
908 if ( verbose & VERB_PROCESS ) {
909 cout << "Tilt axis angle: " << tilt_axis*180.0/M_PI << " degrees" << endl;
910 cout << "Tilt angle range: " << tilt_neg*180.0/M_PI << " - " << tilt_pos*180.0/M_PI << " degrees" << endl;
911 cout << "Origin: " << ori << endl;
912 }
913
914 long i, nn, xx, yy, zz, cc, nv(0);
915 double d, dx, dy, dz, dx2, dy2, dz2, dn, dp;
916 double ax(cos(tilt_axis));
917 double ay(sin(tilt_axis));
918 double an(tan(fabs(tilt_neg) - M_PI_2));
919 double ap(tan(M_PI_2 - fabs(tilt_pos)));
920
921 double max_rad(1);
922 if ( resolution > image->sampling()[0] ) max_rad = image->sampling()[0]/resolution;
923 double max_rad_sq(max_rad*max_rad); // Maximum radius squared on map scale
924
925 for ( i=nn=0; nn<n; nn++ ) {
926 // image[nn].origin(origin);
927 image[nn].origin(ori);
928 for ( zz=0; zz<z; zz++ ) {
929 dz = ((double)zz - ori[2])/z;
930 if ( dz < -0.5 ) dz += 1;
931 if ( dz >= 0.5 ) dz -= 1;
932 dz2 = dz*dz;
933 dn = dz*an;
934 dp = dz*ap;
935 if ( dz < 0 ) swap(dn, dp);
936 for ( yy=0; yy<y; yy++ ) {
937 dy = ((double)yy - ori[1])/y;
938 if ( dy < -0.5 ) dy += 1;
939 if ( dy >= 0.5 ) dy -= 1;
940 dy2 = dy*dy;
941 for ( xx=0; xx<x; xx++, i+=c ) {
942 dx = ((double)xx - ori[0])/x;
943 if ( dx < -0.5 ) dx += 1;
944 if ( dx >= 0.5 ) dx -= 1;
945 dx2 = dx*dx;
946 if ( dx2 + dy2 + dz2 < max_rad_sq ) {
947 d = dx*ay - dy*ax;
948 if ( d < dn || d > dp ) {
949 for ( cc=0; cc<c; cc++ ) set(i+cc, 1);
950 nv += c;
951 }
952 }
953 }
954 }
955 }
956 }
957
958 if ( verbose & VERB_PROCESS )
959 cout << "Number of pixels in mask: " << nv << endl << endl;
960
961 return nv;
962 }
963
981 long Bimage::mask_missing_pyramid(Vector3<double> ori, double tilt_axis1,
982 double tilt_axis2, double tilt_neg1, double tilt_pos1,
983 double tilt_neg2, double tilt_pos2, double resolution)
984 {
985 change_type(UCharacter);
986 clear();
987
988 if ( verbose & ( VERB_LABEL | VERB_PROCESS ) )
989 cout << "Generating a mask with a missing pyramid" << endl;
990
991 if ( verbose & VERB_PROCESS ) {
992 cout << "Tilt axis angle 1: " << tilt_axis1*180.0/M_PI << " degrees" << endl;
993 cout << "Tilt angle range 1: " << tilt_neg1*180.0/M_PI << " - " << tilt_pos1*180.0/M_PI << " degrees" << endl;
994 cout << "Tilt axis angle 2: " << tilt_axis2*180.0/M_PI << " degrees" << endl;
995 cout << "Tilt angle range 2: " << tilt_neg2*180.0/M_PI << " - " << tilt_pos2*180.0/M_PI << " degrees" << endl;
996 cout << "Origin: " << ori << endl;
997 }
998
999 long i, nn, xx, yy, zz, cc, nv(0);
1000 double d1, d2, dx, dy, dz, dx2, dy2, dz2, dn1, dp1, dn2, dp2;
1001 double ax1(cos(tilt_axis1));
1002 double ay1(sin(tilt_axis1));
1003 double ax2(cos(tilt_axis2));
1004 double ay2(sin(tilt_axis2));
1005 double an1(tan(fabs(tilt_neg1) - M_PI_2));
1006 double ap1(tan(M_PI_2 - fabs(tilt_pos1)));
1007 double an2(tan(fabs(tilt_neg2) - M_PI_2));
1008 double ap2(tan(M_PI_2 - fabs(tilt_pos2)));
1009
1010 double max_rad(1);
1011 if ( resolution > image->sampling()[0] ) max_rad = image->sampling()[0]/resolution;
1012 double max_rad_sq(max_rad*max_rad); // Maximum radius squared on map scale
1013
1014 for ( i=nn=0; nn<n; nn++ ) {
1015 image[nn].origin(ori);
1016 for ( zz=0; zz<z; zz++ ) {
1017 dz = ((double)zz - ori[2])/z;
1018 if ( dz < -0.5 ) dz += 1;
1019 if ( dz >= 0.5 ) dz -= 1;
1020 dz2 = dz*dz;
1021 dn1 = dz*an1;
1022 dp1 = dz*ap1;
1023 if ( dn1 > dp1 ) swap(dn1, dp1);
1024 dn2 = dz*an2;
1025 dp2 = dz*ap2;
1026 if ( dn2 > dp2 ) swap(dn2, dp2);
1027 for ( yy=0; yy<y; yy++ ) {
1028 dy = ((double)yy - ori[1])/y;
1029 if ( dy < -0.5 ) dy += 1;
1030 if ( dy >= 0.5 ) dy -= 1;
1031 dy2 = dy*dy;
1032 for ( xx=0; xx<x; xx++, i+=c ) {
1033 dx = ((double)xx - ori[0])/x;
1034 if ( dx < -0.5 ) dx += 1;
1035 if ( dx >= 0.5 ) dx -= 1;
1036 dx2 = dx*dx;
1037 if ( dx2 + dy2 + dz2 < max_rad_sq ) {
1038 d1 = dx*ay1 - dy*ax1;
1039 d2 = dx*ay2 - dy*ax2;
1040 if ( d1 < dn1 || d1 > dp1 || d2 < dn2 || d2 > dp2 ) {
1041 for ( cc=0; cc<c; cc++ ) set(i+cc, 1);
1042 nv += c;
1043 }
1044 }
1045 }
1046 }
1047 }
1048 }
1049
1050 if ( verbose & VERB_PROCESS )
1051 cout << "Number of pixels in mask: " << nv << endl << endl;
1052
1053 return nv;
1054 }
1055
1068 long Bimage::mask_missing_cone(Vector3<double> ori,
1069 double mis_ang, double resolution)
1070 {
1071 change_type(UCharacter);
1072 clear();
1073
1074 if ( verbose & ( VERB_LABEL | VERB_PROCESS ) )
1075 cout << "Generating a mask with a missing cone" << endl;
1076
1077 if ( verbose & VERB_PROCESS ) {
1078 cout << "Cone angle: " << mis_ang*180.0/M_PI << " degrees" << endl;
1079 cout << "Origin: " << ori << endl;
1080 }
1081
1082 long i, nn, xx, yy, zz, cc, nv(0);
1083 double dx, dy, dz, dx2, dy2, dz2, d2;
1084
1085 double max_rad(1);
1086 if ( resolution > image->sampling()[0] ) max_rad = image->sampling()[0]/resolution;
1087 double max_rad_sq(max_rad*max_rad); // Maximum radius squared on map scale
1088
1089 for ( i=nn=0; nn<n; nn++ ) {
1090 image[nn].origin(ori);
1091 for ( zz=0; zz<z; zz++ ) {
1092 dz = ((double)zz - ori[2])/z;
1093 if ( dz < -0.5 ) dz += 1;
1094 if ( dz >= 0.5 ) dz -= 1;
1095 dz2 = dz*dz;
1096 dz = fabs(dz);
1097 d2 = dz*tan(M_PI_2 - mis_ang);
1098 d2 *= d2;
1099 for ( yy=0; yy<y; yy++ ) {
1100 dy = ((double)yy - ori[1])/y;
1101 if ( dy < -0.5 ) dy += 1;
1102 if ( dy >= 0.5 ) dy -= 1;
1103 dy2 = dy*dy;
1104 for ( xx=0; xx<x; xx++, i+=c ) {
1105 dx = ((double)xx - ori[0])/x;
1106 if ( dx < -0.5 ) dx += 1;
1107 if ( dx >= 0.5 ) dx -= 1;
1108 dx2 = dx*dx;
1109 if ( dx2 + dy2 + dz2 < max_rad_sq ) {
1110 if ( dx2 + dy2 > d2 ) {
1111 for ( cc=0; cc<c; cc++ ) set(i+cc, 1);
1112 nv += c;
1113 }
1114 }
1115 }
1116 }
1117 }
1118 }
1119
1120 if ( verbose & VERB_PROCESS )
1121 cout << "Number of pixels in mask: " << nv << endl << endl;
1122
1123 return nv;
1124 }
1125
1126 //#include "rwimg.h"
1127
1140 long Bimage::mask_missing_find(Vector3<double> ori, double resolution, Bstring& mis_type)
1141 {
1142 if ( verbose & ( VERB_LABEL | VERB_PROCESS ) )
1143 cout << "Finding missing regions and creating a missing mask" << endl;
1144
1145 power_spectrum(0);
1146
1147 long i, xx, yy, nz(14), hx(x/2), hy(y/2), nr(x), na(180), ia, ir, nv(0);
1148 double v, a, sa(M_PI*1.0/na), vmin, vmax, ax, amin(0), amax(0), r, f;
1149 Vector3<long> st(0,0,nz), sz(x,y,1);
1150 Vector3<double> d;
1151
1152 Bimage* pex = extract(0, st, sz);
1153
1154 Bimage* ps = new Bimage(Float, TSimple, nr, na, 1, 1);
1155
1156 for ( i=yy=0; yy<y; ++yy ) {
1157 d[1] = (yy < hy)? yy: yy - y;
1158 for ( xx=0; xx<x; ++xx, ++i ) {
1159 d[0] = (xx < hx)? xx: xx - x;
1160 v = (*pex)[i];
1161 for ( ia=0; ia<na; ++ia ) {
1162 a = sa*ia;
1163 r = cos(a)*d[1] - sin(a)*d[0];
1164 // r = cos(a)*d[0] + sin(a)*d[1];
1165 if ( r < 0 ) r += nr;
1166 ir = (long)r;
1167 f = r - ir;
1168 if ( ir < 0 ) ir += nr;
1169 if ( ir >= 0 && ir < nr )
1170 ps->add(ia*nr + ir, (1-f)*v);
1171 ir++;
1172 if ( ir >= nr ) ir -= nr;
1173 if ( ir >= 0 && ir < nr )
1174 ps->add(ia*nr + ir, f*v);
1175 }
1176 }
1177 }
1178
1179 // write_img("ps.pif", ps, 0);
1180
1181 ax = 0;
1182 vmin = 1e30;
1183 for ( ia=0; ia<na; ++ia ) {
1184 v = 0;
1185 for ( ir=0, i=ia*nr; ir<nz; ++ir, ++i )
1186 v += (*ps)[i];
1187 if ( vmin > v ) {
1188 vmin = v;
1189 ax = ia;
1190 }
1191 // cout << ia << tab << v << endl;
1192 }
1193 ia = ax;
1194 ax = M_PI*ax/na;
1195 i = ia*nr;
1196 vmax = 0;
1197 vmin = 0;
1198 v = (*ps)[i];
1199 for ( ir=0; ir<nr; ++ir, ++i ) {
1200 f = (*ps)[i] - v;
1201 // cout << ir << tab << f << endl;
1202 if ( vmin > f ) {
1203 vmin = f;
1204 amin = ir;
1205 }
1206 if ( vmax < f ) {
1207 vmax = f;
1208 amax = ir;
1209 }
1210 v = (*ps)[i];
1211 }
1212 amin = -atan2(-nz, nr - amin);
1213 amax = -atan2(nz, amax);
1214
1215 if ( verbose & VERB_FULL ) {
1216 cout << "Axis angle: " << ax*180.0/M_PI << endl;
1217 cout << "Minimum tilt angle: " << amax*180.0/M_PI << endl;
1218 cout << "Maximum tilt angle: " << amin*180.0/M_PI << endl;
1219 }
1220
1221 delete pex;
1222 delete ps;
1223
1224 // change_type(UCharacter);
1225 // clear();
1226 mask_missing_wedge(ori, ax, amax, amin, resolution);
1227
1228 if ( verbose & VERB_PROCESS )
1229 cout << "Number of pixels in mask: " << nv << endl << endl;
1230
1231 return nv;
1232 }
1233
1247 long Bimage::mask_pack_plane(Matrix3 mat, double hi_res, double scale)
1248 {
1249 if ( hi_res < 2*image->sampling()[0] ) hi_res = 2*image->sampling()[0];
1250
1251 long j;
1252 double w, d2;
1253 Vector3<long> coor;
1254 Vector3<double> m, dist, iv;
1255
1256 Vector3<double> invsize(1.0/x, 1.0/y, 1.0/z);
1257 Vector3<double> vscale(1/scale, 1/scale, z*1.0/(scale*x));
1258 // mat = mat.transpose();
1259 mat = vscale * mat; // Matrix includes scaling going from image to map
1260
1261 if ( verbose & VERB_FULL ) {
1262 cout << "Packing a mask into reciprocal space up to " << hi_res << " A resolution" << endl;
1263 cout << "Transformation matrix:" << endl;
1264 cout << mat << endl;
1265 cout << endl;
1266 }
1267
1268 double max_rad(image->sampling()[0]/hi_res);
1269 if ( max_rad > 0.5 ) max_rad = 0.5;
1270 double max_rad_sq = max_rad*max_rad; // Maximum radius squared on map scale
1271 // cout << "max_rad_sq = " << max_rad_sq << endl;
1272 double ymin = floor(-max_rad*x);
1273 double ymax = -ymin;
1274 double xmin = floor(-max_rad*x);
1275 double xmax = -xmin;
1276
1277 for ( iv[1]=ymin; iv[1]<=ymax; iv[1]+=1 ) {
1278 for ( iv[0]=xmin; iv[0]<=xmax; iv[0]+=1 ) {
1279 m = mat * iv;
1280 d2 = (m * invsize).length2();
1281 if ( d2 < max_rad_sq ) {
1282 coor = Vector3<long>((long) floor(m[0] + 0.5),
1283 (long) floor(m[1] + 0.5),
1284 (long) floor(m[2] + 0.5));
1285 dist = m - coor;
1286 w = 1 - dist.length();
1287 if ( w > 1e-6 ) {
1288 j = index_wrap(coor);
1289 set(j, 1);
1290 }
1291 }
1292 }
1293 }
1294
1295 return 0;
1296 }
1297
1298
1308 double Bimage::variance_threshold(double lowvar)
1309 {
1310 double varmax(max);
1311 if ( varmax <= lowvar ) varmax = 1;
1312
1313 long i;
1314 long nfg(0), nbg(0);
1315 double snr(0), t(0), v, vfg(varmax), vbg(0);
1316 double dvfg(varmax), dvbg(varmax), dt(lowvar), sumfg, sumbg;
1317
1318 while ( fabs(dvfg) > dt || fabs(dvbg) > dt ) {
1319 nfg = nbg = 0;
1320 sumfg = sumbg = 0;
1321 t = (vbg + vfg)/2;
1322 for ( i=0; i<datasize; i++ ) {
1323 v = (*this)[i];
1324 if ( v > dt ) {
1325 if ( v > t ) {
1326 sumfg += v;
1327 nfg++;
1328 } else {
1329 sumbg += v;
1330 nbg++;
1331 }
1332 }
1333 }
1334 if ( nfg ) sumfg /= nfg;
1335 if ( nbg ) sumbg /= nbg;
1336 dvfg = sumfg - vfg;
1337 dvbg = sumbg - vbg;
1338 vfg = sumfg;
1339 vbg = sumbg;
1340 }
1341
1342 snr = vfg/vbg - 1;
1343 image->FOM(snr);
1344
1345 if ( verbose ) {
1346 cout << "Background variance: " << vbg << " (" << nbg << " voxels, " << nbg*100.0/datasize << " %)" << endl;
1347 cout << "Foreground variance: " << vfg << " (" << nfg << " voxels, " << nfg*100.0/datasize << " %)" << endl;
1348 cout << "Signal-to-noise ratio: " << snr << endl << endl;
1349 }
1350
1351 return t;
1352 }
1353
1367 Bimage* Bimage::variance_mask(long kernel_size, double lowvar, int bkg_flag)
1368 {
1369 Bimage* pvar = copy();
1370
1371 pvar->variance(kernel_size);
1372
1373 long i;
1374 double t(pvar->variance_threshold(lowvar)), v;
1375
1376 Bimage* pmask = copy_header();
1377 pmask->data_type(SCharacter);
1378 pmask->data_alloc();
1379
1380 if ( verbose ) {
1381 cout << "Generating a variance mask:" << endl;
1382 cout << "Thresholding local variance to: " << t << endl;
1383 cout << "Low variance threshold: " << lowvar << endl << endl;
1384 }
1385
1386 if ( bkg_flag == 0 ) { // Set only foreground
1387 for ( i=0; i<datasize; i++ )
1388 if ( (*pvar)[i] > t ) pmask->set(i, 1); // Foreground
1389 } else for ( i=0; i<datasize; i++ ) {
1390 v = (*pvar)[i];
1391 if ( v > t ) pmask->set(i, 1); // Foreground
1392 else if ( v >= lowvar ) pmask->set(i, -1); // Background
1393 }
1394
1395 image->FOM(pvar->image->FOM());
1396 pmask->image->FOM(pvar->image->FOM());
1397
1398 delete pvar;
1399
1400 pmask->statistics();
1401
1402 // write_img("t.pif", pmask);
1403
1404 return pmask;
1405 }
1406
1415 Bimage* Bimage::tile_mask(long step)
1416 {
1417 Bimage* pmask = copy_header(1);
1418 pmask->data_type(Integer);
1419 pmask->compound_type(TSimple);
1420 pmask->channels(1);
1421 pmask->data_alloc();
1422
1423 long i, xx, yy, zz, tx, ty, tz, ti;
1424 long sx = (x - 1)/step + 1;
1425 long sy = (y - 1)/step + 1;
1426
1427 for ( i=zz=0; zz<z; zz++ ) {
1428 tz = zz/step;
1429 for ( yy=0; yy<y; yy++ ) {
1430 ty = yy/step;
1431 for ( xx=0; xx<x; xx++, i++ ) {
1432 tx = xx/step;
1433 ti = (tz*sy + ty)*sx + tx;
1434 pmask->set(i, ti);
1435 }
1436 }
1437 }
1438
1439 pmask->statistics();
1440
1441 return pmask;
1442 }
1443
1453 long Bimage::mask_split(long voxels_per_level)
1454 {
1455 if ( c > 1 ) {
1456 cerr << "Error: Multi-channel masks cannot be converted to multi-level masks!" << endl;
1457 return 0;
1458 }
1459
1460 long i, k, nv;
1461 double value, threshold(0.5);
1462 int* mask = new int[datasize];
1463
1464 if ( threshold > max/2 ) threshold = max/2;
1465
1466 if ( verbose & VERB_PROCESS ) {
1467 cout << "Splitting a mask into multiple levels:" << endl;
1468 cout << "Voxels per level: " << voxels_per_level << endl;
1469 cout << "Threshold: " << threshold << endl;
1470 }
1471
1472 for ( i=nv=0, k=1; i<datasize; i++ ) {
1473 value = (*this)[i];
1474 if ( value > threshold ) {
1475 mask[i] = k;
1476 nv++;
1477 } else mask[i] = 0;
1478 if ( nv >= voxels_per_level ) {
1479 nv = 0;
1480 k++;
1481 }
1482 }
1483
1484 if ( verbose & VERB_PROCESS )
1485 cout << "Levels generated: " << k << endl << endl;
1486
1487 data_type(Integer);
1488
1489 data_assign((unsigned char *) mask);
1490
1491 statistics();
1492
1493 return nv;
1494 }
1495
1503 long Bimage::levelmask_collapse()
1504 {
1505 if ( verbose & VERB_LABEL )
1506 cout << "Collapsing a multi-level mask with " << max << " levels" << endl << endl;
1507
1508 long i, nv;
1509 int value;
1510 unsigned char* mask = new unsigned char[datasize];
1511
1512 for ( i=nv=0; i<datasize; i++ ) {
1513 value = (int) (*this)[i];
1514 if ( value > 0 ) {
1515 mask[i] = 1;
1516 nv++;
1517 } else mask[i] = 0;
1518 }
1519
1520 if ( verbose & VERB_PROCESS )
1521 cout << "Number of voxels retained: " << nv << " (" << nv*100.0/datasize << " %)" << endl;
1522
1523 data_type(UCharacter);
1524
1525 data_assign(mask);
1526
1527 statistics();
1528
1529 return nv;
1530 }
1531
1541 long Bimage::levelmask_add(Bimage* pmask, int add_level)
1542 {
1543 long i;
1544
1545 if ( verbose & VERB_PROCESS )
1546 cout << "Add mask " << pmask->file_name() << " at level " << add_level << endl << endl;
1547
1548 for ( i=0; i<data_size(); ++i )
1549 if ( (*pmask)[i] > 0.5 ) set(i, add_level);
1550
1551 statistics();
1552
1553 return 0;
1554 }
1555
1565 long Bimage::levelmask_dilate(int times)
1566 {
1567 int t;
1568
1569 for ( t=0; t<times; t++ )
1570 levelmask_dilate();
1571
1572 return 0;
1573 }
1574
1583 long Bimage::levelmask_dilate()
1584 {
1585 long i, j, im, nn, xx, yy, zz, kx, ky, kz;
1586 long vmax(max+1), v;
1587
1588 Vector3<long> k(3, 3, 3);
1589 k = k.min(size());
1590
1591 Vector3<long> kh(k/2);
1592 Vector3<long> lo, hi;
1593
1594 if ( verbose & VERB_PROCESS )
1595 cout << "Dilating a level mask" << endl << endl;
1596
1597 int* lev = new int[vmax];
1598
1599 unsigned char* mask = new unsigned char[data_size()];
1600 for ( i=0; i<data_size(); i++ ) mask[i] = (*this)[i];
1601
1602 for ( i=nn=0; nn<n; nn++ ) {
1603 for ( zz=0; zz<z; zz++ ) {
1604 lo[2] = (zz > kh[2])? zz - kh[2]: 0;
1605 hi[2] = (zz+kh[2] < z)? zz + kh[2]: z - 1;
1606 for ( yy=0; yy<y; yy++ ) {
1607 lo[1] = (yy > kh[1])? yy - kh[1]: 0;
1608 hi[1] = (yy+kh[1] < y)? yy + kh[1]: y - 1;
1609 for ( xx=0; xx<x; xx++, i++ ) {
1610 lo[0] = (xx > kh[0])? xx - kh[0]: 0;
1611 hi[0] = (xx+kh[0] < x)? xx + kh[0]: x - 1;
1612 if ( mask[i] < 1 ) {
1613 for ( j=0; j<vmax; j++ ) lev[j] = 0;
1614 for ( kz=lo[2]; kz<=hi[2]; kz++ ) {
1615 for ( ky=lo[1]; ky<=hi[1]; ky++ ) {
1616 for ( kx=lo[0]; kx<=hi[0]; kx++ ) {
1617 j = index(kx, ky, kz, nn);
1618 lev[mask[j]]++;
1619 }
1620 }
1621 }
1622 for ( j=1, v=im=0; j<vmax; j++ ) if ( v < lev[j] ) {
1623 im = j;
1624 v = lev[j];
1625 }
1626 if ( v ) set(i, im);
1627 }
1628 }
1629 }
1630 }
1631 }
1632
1633 delete[] mask;
1634 delete[] lev;
1635
1636 statistics();
1637
1638 return 0;
1639 }
1640
1650 long Bimage::levelmask_select(Bstring& select_list)
1651 {
1652 if ( verbose & VERB_LABEL )
1653 cout << "Selecting levels " << select_list << endl;
1654
1655 long i, nv;
1656 long nlev = (long) max + 1;
1657 int value;
1658
1659 int* lev = new int[nlev];
1660 for ( i=0; i<nlev; i++ ) lev[i] = 0;
1661
1662 select_numbers(select_list, nlev, lev);
1663
1664 int* mask = new int[datasize];
1665
1666 for ( i=nv=0; i<datasize; i++ ) {
1667 value = (int) (*this)[i];
1668 if ( value >= 0 && value < nlev && lev[value] ) {
1669 mask[i] = value;
1670 nv++;
1671 } else mask[i] = 0;
1672 }
1673
1674 delete[] lev;
1675
1676 if ( verbose & VERB_PROCESS )
1677 cout << "Number of voxels retained: " << nv << " (" << nv*100.0/datasize << " %)" << endl << endl;
1678
1679 data_type(Integer);
1680
1681 data_assign((unsigned char *) mask);
1682
1683 statistics();
1684
1685 return nv;
1686 }
1687
1698 long Bimage::levelmask_select(long nn, Vector3<long> voxel)
1699 {
1700 if ( verbose & VERB_LABEL )
1701 cout << "Selecting level from voxel: " << voxel << endl;
1702
1703 long i, nv;
1704 long level, value;
1705
1706 i = index(voxel, nn);
1707 level = (long) (*this)[i];
1708
1709 for ( i=nv=0; i<datasize; i++ ) {
1710 value = (long) (*this)[i];
1711 if ( fabs(value - level) < 0.5 ) {
1712 set(i, 1);
1713 nv++;
1714 } else set(i, 0);
1715 }
1716
1717 if ( verbose & VERB_PROCESS )
1718 cout << "Number of voxels retained: " << nv << " (" << nv*100.0/datasize << " %)" << endl << endl;
1719
1720 statistics();
1721
1722 return nv;
1723 }
1724
1733 long Bimage::levelmask_select(Bimage* pmask)
1734 {
1735 long i;
1736 long v;
1737 long nsel(0), nlevel((long) (max + 1));
1738 int* levels = new int[nlevel];
1739
1740 if ( verbose ) {
1741 cout << "Selecting levels overlapping with a mask:" << endl;
1742 cout << "Mask file: " << pmask->file_name() << endl;
1743 cout << "Input levels: " << nlevel-1 << endl;
1744 }
1745
1746 for ( i=0; i<nlevel; i++ ) levels[i] = 0;
1747
1748 for ( i=0; i<datasize; i++ ) {
1749 v = (long) (*this)[i];
1750 if ( (*pmask)[i] > 0.5 && v > 0 )
1751 levels[v]++;
1752 }
1753
1754 for ( i=0; i<nlevel; i++ ) if ( levels[i] > 0 ) nsel++;
1755
1756 if ( verbose ) {
1757 cout << "Selected levels: " << nsel << endl << endl;
1758 cout << "Level\tCount" << endl;
1759 for ( i=0; i<nlevel; i++ ) if ( levels[i] )
1760 cout << i << tab << levels[i] << endl;
1761 cout << endl;
1762 }
1763
1764 for ( i=0; i<datasize; i++ ) {
1765 v = (long) (*this)[i];
1766 if ( v < 1 || levels[v] < 1 )
1767 set(i, 0);
1768 }
1769
1770 delete[] levels;
1771
1772 return nsel;
1773 }
1774
1785 Bimage* Bimage::level_mask_extract(Bimage* pmask)
1786 {
1787 long i, j, k, cc;
1788 long imgsize(x*y*z);
1789
1790 Bimage* pex = new Bimage(datatype, compoundtype, size(), (long) pmask->maximum());
1791 pex->sampling(sampling());
1792 for ( i=0; i<pex->images(); i++ ) pex->image[i] = image[0];
1793
1794 if ( verbose & VERB_PROCESS )
1795 cout << "Excising " << pex->images() << " regions" << endl << endl;
1796
1797 for ( i=0; i<imgsize; i++ ) if ( (*pmask)[i] > 0 ) {
1798 j = (((long)(*pmask)[i] - 1)*imgsize + i)*c;
1799 for ( cc=0, k=i*c; cc<c; cc++, j++, k++ ) pex->set(j, (*this)[k]);
1800 }
1801
1802 return pex;
1803 }
1804
1809 double Bimage::levelmask_average_region_size()
1810 {
1811 long i;
1812 long v, nr(0);
1813 long nl((long) (max + 1.9));
1814 int* f = new int[nl];
1815 double a(0);
1816
1817 for ( i=0; i<nl; i++ ) f[i] = 0;
1818
1819 for ( i=0; i<datasize; i++ ) {
1820 v = (long) (*this)[i];
1821 if ( v > 0 ) f[v]++;
1822 }
1823
1824 for ( i=0; i<nl; i++ ) if ( f[i] ) {
1825 a += f[i];
1826 nr++;
1827 // cout << nr << tab << f[i] << endl;
1828 }
1829
1830 if ( nr ) a /= nr;
1831
1832 if ( verbose & VERB_FULL ) {
1833 cout << "Number of regions: " << nr << endl;
1834 cout << "Average region size: " << a << endl << endl;
1835 }
1836
1837 delete[] f;
1838
1839 return a;
1840 }
1841
1849 long Bimage::levelmask_clean()
1850 {
1851 change_type(Integer);
1852
1853 long i, j, m;
1854
1855 for ( i=m=0; i<datasize; i++ )
1856 if ( m < (*this)[i] )
1857 m = (long) (*this)[i];
1858
1859 m++;
1860
1861 int* map = new int[m];
1862
1863 for ( i=0; i<m; i++ ) map[i] = 0;
1864
1865 for ( i=0; i<datasize; i++ ) if ( (*this)[i] > 0 ) map[(int)(*this)[i]] += 1;
1866
1867 for ( i=j=1; i<m; i++ ) if ( map[i] ) map[i] = j++;
1868
1869 for ( i=0; i<datasize; i++ ) if ( (*this)[i] > 0 ) set(i, map[(int)(*this)[i]]);
1870
1871 delete[] map;
1872
1873 statistics();
1874
1875 return 0;
1876 }
1877
1887 long Bimage::levelmask_colorize()
1888 {
1889 random_seed();
1890
1891 long i, cc, nc((long) (max - min + 1));
1892 RGB<unsigned char>* lut = new RGB<unsigned char>[nc];
1893
1894 for ( cc=0; cc<nc; cc++ ) lut[cc].random_color();
1895
1896 if ( verbose & VERB_LABEL ) {
1897 cout << "Coloring a multi-level mask:" << endl;
1898 cout << "Levels: " << nc << endl << endl;
1899 }
1900
1901 RGB<unsigned char>* nudata = new RGB<unsigned char>[datasize];
1902
1903 for ( i=0; i<datasize; i++ ) {
1904 cc = (long) (*this)[i] - min;
1905 nudata[i] = lut[cc];
1906 }
1907
1908 delete[] lut;
1909
1910 data_type(UCharacter);
1911 compound_type(TRGB);
1912 c = 3;
1913
1914 data_assign((unsigned char *) nudata);
1915
1916 return 0;
1917 }
1918
1924 Bimage* Bimage::levelmask_color_by_size()
1925 {
1926 Bimage* pcol = new Bimage(UCharacter, TRGB, size(), n);
1927 pcol->sampling(sampling());
1928 pcol->origin(image->origin());
1929 RGB<unsigned char>* color = (RGB<unsigned char> *) pcol->data_pointer();
1930
1931 if ( verbose )
1932 cout << "Coloring mask levels by size" << endl;
1933
1934 long i, j, nseg((long)(max+ 1.9));
1935 long vmin(datasize), vmax(0);
1936 double vavg(0), vstd(0);
1937 RGB<unsigned char> black(0,0,0);
1938 int* vol = new int[nseg];
1939
1940 for ( i=0; i<nseg; i++ ) vol[i] = 0;
1941
1942 for ( i=0; i<datasize; i++ )
1943 if ( (*this)[i] > -1 ) vol[(long)(*this)[i]]++;
1944
1945 for ( i=1; i<nseg; i++ ) {
1946 if ( vmin > vol[i] ) vmin = vol[i];
1947 if ( vmax < vol[i] ) vmax = vol[i];
1948 vavg += vol[i];
1949 vstd += vol[i] * vol[i];
1950 }
1951 vavg /= nseg - 1;
1952 vstd /= nseg - 1;
1953 vstd -= vavg * vavg;
1954 vstd = sqrt(vstd);
1955 if ( vmin < vavg - 3*vstd ) vmin = vavg - 3*vstd;
1956 if ( vmax > vavg + 3*vstd ) vmax = vavg + 3*vstd;
1957
1958 if ( verbose )
1959 cout << "Coloring range: " << vmin << " - " << vmax << endl;
1960
1961 for ( i=0; i<datasize; i++ ) {
1962 j = (*this)[i];
1963 if ( j > 0 )
1964 color[i].spectrum(vol[j], vmin, vmax);
1965 else
1966 color[i] = black;
1967 }
1968
1969 delete[] vol;
1970
1971 pcol->statistics();
1972
1973 return pcol;
1974 }
1975
1981 int Bimage::levelmask_region_size()
1982 {
1983 change_type(Integer);
1984
1985 if ( verbose )
1986 cout << "Generating a region size level mask" << endl;
1987
1988 long i, j, nseg((long)(max+1.9));
1989 // long vmin(datasize), vmax(0);
1990 // double vavg(0), vstd(0);
1991 int* vol = new int[nseg];
1992
1993 for ( i=0; i<nseg; i++ ) vol[i] = 0;
1994
1995 for ( i=0; i<datasize; i++ )
1996 if ( (*this)[i] > -1 ) vol[(long)(*this)[i]]++;
1997
1998 for ( i=0; i<datasize; i++ ) {
1999 j = (*this)[i];
2000 if ( j > 0 )
2001 set(i, vol[j]);
2002 else
2003 set(i, 0);
2004 }
2005
2006 statistics();
2007
2008 delete[] vol;
2009
2010 return 0;
2011 }
2012
2018 Bplot* Bimage::levelmask_size_histogram()
2019 {
2020 if ( verbose )
2021 cout << "Generating a mask level size histogram" << endl;
2022
2023 long i, j, nseg((long)(max+ 1.9));
2024 long vmin(datasize), vmax(0);
2025 double vavg(0), vstd(0);
2026 int* vol = new int[nseg];
2027
2028 for ( i=0; i<nseg; i++ ) vol[i] = 0;
2029
2030 for ( i=0; i<datasize; i++ )
2031 if ( (*this)[i] > -1 ) vol[(long)(*this)[i]]++;
2032
2033 for ( i=1; i<nseg; i++ ) {
2034 // cout << i << tab << vol[i] << endl;
2035 if ( vmin > vol[i] ) vmin = vol[i];
2036 if ( vmax < vol[i] ) vmax = vol[i];
2037 vavg += vol[i];
2038 vstd += vol[i] * vol[i];
2039 }
2040 vavg /= nseg - 1;
2041 vstd /= nseg - 1;
2042 vstd -= vavg * vavg;
2043 vstd = sqrt(vstd);
2044 // cout << "Stats:" << tab << vmin << tab << vmax << tab << vavg << tab << vstd << endl;
2045 if ( vmin < vavg - 3*vstd ) vmin = vavg - 3*vstd;
2046 if ( vmax > vavg + 3*vstd ) vmax = vavg + 3*vstd;
2047 // cout << "Stats:" << tab << vmin << tab << vmax << tab << vavg << tab << vstd << endl;
2048
2049 long bins(256);
2050 double scale = bins*1.0/(vmax - vmin);
2051 int* h = new int[bins];
2052 for ( i=0; i<bins; i++ ) h[i] = 0;
2053
2054 for ( i=1; i<nseg; i++ ) {
2055 j = (long) (vol[i] - vmin)*scale;
2056 if ( j < 0 ) j = 0;
2057 if ( j >= bins ) j = bins - 1;
2058 h[j]++;
2059 }
2060
2061 delete[] vol;
2062
2063 long ncol(2);
2064 Bstring title("Histogram of level sizes");
2065 Bplot* plot = new Bplot(1, bins, ncol);
2066 plot->title(title);
2067
2068 plot->page(0).title(title);
2069 plot->page(0).columns(ncol);
2070 for ( i=0; i<ncol; i++ ) plot->page(0).column(i).number(i);
2071 plot->page(0).column(0).label("Bin");
2072 plot->page(0).column(0).axis(1);
2073 plot->page(0).column(1).type(1);
2074 plot->page(0).column(1).label("Count");
2075 plot->page(0).column(1).axis(3);
2076 plot->page(0).column(1).element_size(0.5);
2077 plot->page(0).column(1).color(0.7,0.7,0.7);
2078 plot->page(0).axis(1).min(vmin);
2079 plot->page(0).axis(1).max(vmax);
2080 // plot->page(0).axis(3).min(0);
2081 // plot->page(0).axis(3).max(hmax);
2082
2083 for ( i=0, j=bins; i<bins; i++, j++ ) {
2084 (*plot)[i] = vmin + i/scale;
2085 (*plot)[j] = h[i];
2086 }
2087
2088 delete[] h;
2089
2090 return plot;
2091 }
2092
2106 Matrix Bimage::mask_interface_matrix(int img_num)
2107 {
2108 long ns(img_num), ne(img_num);
2109 if ( img_num < 0 ) {
2110 ns = 0;
2111 ne = n - 1;
2112 }
2113
2114 long i, j, xx, yy, zz, nn, kx, ky, kz, m(max+1.9);
2115 long vi, vj;
2116 long xlo, xhi, ylo, yhi, zlo, zhi;
2117 long imgsize(x*y*z);
2118 long ds(imgsize*n);
2119
2120 for ( i=m=0; i<ds; i++ ) if ( m < (*this)[i] ) m = (long) (*this)[i];
2121 m++;
2122
2123 if ( verbose & VERB_PROCESS )
2124 cout << "Calculating an interface matrix of " << m << " x " << m << endl;
2125
2126 int* tmp = new int[m];
2127 Matrix ifmat = Matrix(m,m);
2128
2129 for ( nn=ns, i=nn*imgsize; nn<=ne; nn++ ) {
2130 for ( zz=0; zz<z; zz++ ) {
2131 zlo = (zz>0)? zz-1: zz;
2132 zhi = (zz<z-1)? zz+1: zz;
2133 for ( yy=0; yy<y; yy++ ) {
2134 ylo = (yy>0)? yy-1: yy;
2135 yhi = (yy<y-1)? yy+1: yy;
2136 for ( xx=0; xx<x; xx++, i++ ) {
2137 xlo = (xx>0)? xx-1: xx;
2138 xhi = (xx<x-1)? xx+1: xx;
2139 vi = (int) (*this)[i];
2140 if ( vi >= 0 ) {
2141 for ( j=0; j<m; j++ ) tmp[j] = 0;
2142 for ( kz=zlo; kz<=zhi; kz++ ) {
2143 for ( ky=ylo; ky<=yhi; ky++ ) {
2144 for ( kx=xlo; kx<=xhi; kx++ ) {
2145 j = index(0,kx,ky,kz,nn);
2146 vj = (int) (*this)[j];
2147 if ( vj >= 0 && vi != vj )
2148 tmp[vj] = 1;
2149 }
2150 }
2151 }
2152 for ( j=0; j<m; j++ )
2153 if ( tmp[j] ) ifmat[vi][j] += 1;
2154 }
2155 }
2156 }
2157 }
2158 }
2159
2160 delete[] tmp;
2161
2162 return ifmat;
2163 }
2164
2175 long Bimage::mask_region_interfaces(int reg_num)
2176 {
2177 long i, j, m, nadj(0);
2178
2179 Matrix ifmat = mask_interface_matrix(0);
2180 m = ifmat.rows();
2181
2182 if ( reg_num >= 0 ) {
2183 cout << "Interfaces for region " << reg_num << ":" << endl;
2184 cout << "Region\tVin\tVadj" << endl;
2185 for ( i=0; i<m; i++ ) {
2186 if ( i && ifmat[reg_num][i] ) nadj++;
2187 if ( ifmat[reg_num][i] && ifmat[i][reg_num] )
2188 cout << i << tab << ifmat[reg_num][i] << tab << ifmat[i][reg_num] << endl;
2189 }
2190 cout << endl;
2191 cout << "Interfaced regions: " << nadj << endl;
2192 } else {
2193 cout << "Interface matrix:" << endl;
2194 // if ( verbose & VERB_FULL ) {
2195 cout << "Region";
2196 for ( i=0; i<m; i++ ) cout << tab << i;
2197 cout << endl;
2198 for ( j=0; j<m; j++ ) {
2199 cout << j;
2200 for ( i=0; i<m; i++ ) cout << tab << ifmat[j][i];
2201 cout << endl;
2202 }
2203 // }
2204 }
2205 cout << endl;
2206
2207 return 0;
2208 }
2209
2226 long Bimage::mask_merge_delete(long min_size, long min_if)
2227 {
2228 if ( min_if < 1 ) min_if = 1;
2229
2230 // change_type(Integer);
2231
2232 long i, j, k, l, nm, nd, end, nn;
2233 long imgsize(x*y*z);
2234 long ds(imgsize*n);
2235 int m, imax, max;
2236
2237 for ( i=m=0; i<ds; i++ ) if ( m < (*this)[i] ) m = (long)(*this)[i];
2238 m++;
2239
2240 int* cnt = new int[m];
2241 int* map = new int[m];
2242 Matrix ifmat;
2243
2244 if ( verbose ) {
2245 cout << "Eliminating small regions by deletion and merging:" << endl;
2246 cout << "Minimum size: " << min_size << " (" << sampling().volume()*min_size << " A3)" << endl;
2247 cout << "Minimum interface area: " << min_if << " (" << sampling()[0]*sampling()[1]*min_if << " A2)" << endl;
2248 cout << "Regions: " << m << endl;
2249 }
2250
2251 for ( nn=0; nn<n; nn++ ) {
2252 ifmat = mask_interface_matrix(nn);
2253 for ( j=0; j<m; j++ ) cnt[j] = 0;
2254 for ( i=nn*imgsize, j=i+imgsize; i<j; i++ ) cnt[(int)(*this)[i]] += 1;
2255 if ( verbose & VERB_FULL ) {
2256 cout << "Region";
2257 for ( k=1; k<m; k++ ) cout << tab << k;
2258 cout << endl;
2259 for ( j=1; j<m; j++ ) {
2260 cout << j;
2261 for ( k=1; k<m; k++ ) cout << tab << ifmat[j][k];
2262 cout << endl;
2263 }
2264 }
2265 for ( j=1; j<m; j++ ) { // Find the largest interface for small regions
2266 map[j] = j;
2267 if ( cnt[j] < min_size ) {
2268 max = min_if;
2269 if ( max > cnt[j]/2 ) max = cnt[j]/2; // Change the interface cutoff for really small regions
2270 if ( max < 1 ) max = 1;
2271 for ( k=1, imax=0; k<m; k++ ) {
2272 if ( max <= ifmat[j][k] ) {
2273 max = ifmat[j][k];
2274 imax = k;
2275 }
2276 }
2277 map[j] = imax;
2278 }
2279 }
2280 // delete[] ifmat;
2281 if ( verbose & VERB_FULL ) {
2282 cout << "Region\tPointer" << endl;
2283 for ( j=1; j<m; j++ ) cout << j << tab << map[j] << endl;
2284 }
2285 for ( j=1; j<m; j++ ) if ( map[j] != j ) { // Resolve linked references
2286 for ( k=1, cnt[0] = j, end=0; k<m && end==0; k++ ) {
2287 cnt[k] = map[cnt[k-1]];
2288 for ( l=0; l<k && cnt[k] != cnt[l]; l++ ) ; // Detect loops and self-reference
2289 if ( l < k ) { // Set new references
2290 end = cnt[k];
2291 for ( l=0; l<k; l++ ) map[cnt[l]] = end;
2292 }
2293 }
2294 }
2295 for ( j=1, nm=nd=0; j<m; j++ ) { // Re-assign small regions
2296 if ( map[j] != j ) {
2297 if ( map[j] < 1 ) nd++;
2298 for ( k=0, l=n*imgsize; k<imgsize; k++, l++ )
2299 if ( (int)(*this)[l] == j ) set(l, map[j]);
2300 if ( verbose & VERB_FULL )
2301 cout << j << " -> " << map[j] << endl;
2302 } else nm++;
2303 }
2304 }
2305
2306 if ( verbose ) {
2307 cout << "New regions: " << nm << endl;
2308 cout << "Regions deleted: " << nd << endl << endl;
2309 }
2310
2311 delete[] cnt;
2312 delete[] map;
2313
2314 return 0;
2315 }
2316
2330 long Bimage::apply_soft_mask(long nn, Bimage* pmask, int fill_type, double fill)
2331 {
2332 if ( fill_type == FILL_AVERAGE ) fill = avg;
2333 if ( fill_type == FILL_BACKGROUND ) fill = background(nn);
2334
2335 long i, j;
2336
2337 for ( i=0, j=nn*image_size(); i<image_size(); ++i, ++j )
2338 set(j, (*pmask)[i] * (*this)[j] + (1 - (*pmask)[i]) * fill);
2339
2340 return 0;
2341 }
2342
2343
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Bimage::mask_pack_plane
long mask_pack_plane(Matrix3 mat, double hi_res, double scale)
Packs a 2D mask into a 3D reciprocal space volume.
Definition: Bimage_mask.cpp:1247
Bimage::mask
long mask(Bimage *pmask, double fill)
Masks an image.
Definition: Bimage_mask.cpp:26
Bimage::mask_region_interfaces
long mask_region_interfaces(int reg_num)
Reports the whole interface matrix or interfaces for one region only.
Definition: Bimage_mask.cpp:2175
M_PI_2
#define M_PI_2
Definition: utilities.h:62
Bimage::mask_extract
Bimage * mask_extract(Bimage *pmask)
Zeroes everything outside the mask and return the excised feature.
Definition: Bimage_mask.cpp:294
Bimage::copy_header
Bimage * copy_header()
Definition: Bimage.h:650
Bimage::index_wrap
long index_wrap(long nx, long ny, long nz) const
Definition: Bimage.h:401
FILL_BACKGROUND
#define FILL_BACKGROUND
Definition: utilities.h:174
Vector3::normalize
double normalize()
Definition: Vector3.h:236
Bimage.h
Header file for image class.
random_seed
long random_seed()
Gets a random seed and sets the flag.
Definition: random_numbers.cpp:41
Matrix::rows
long rows()
Definition: Matrix.h:153
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::mask_interface_matrix
Matrix mask_interface_matrix(int img_num)
Calculates the interfaces between regions.
Definition: Bimage_mask.cpp:2106
Bplot::title
Bstring & title()
Definition: Bplot.h:189
Bimage::image_size
long image_size()
Definition: Bimage.h:267
Bcolumn::element_size
double element_size()
Definition: Bplot.h:74
Bimage::max_in_kernel
int max_in_kernel(long ksize)
Definition: Bimage_mask.cpp:309
Bimage::mask_stats
long mask_stats()
Calculates statistics for a mask.
Definition: Bimage_mask.cpp:165
Bimage::levelmask_dilate
long levelmask_dilate()
Dilates a level mask.
Definition: Bimage_mask.cpp:1583
Bimage::levelmask_region_size
int levelmask_region_size()
Convert a mask to reflect region sizes.
Definition: Bimage_mask.cpp:1981
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
Bimage::power_spectrum
int power_spectrum(int flags=0)
Calculates a power spectrum.
Definition: Bimage_powerspectrum.cpp:48
Bcolumn::label
Bstring & label()
Definition: Bplot.h:63
Bimage::mask_by_threshold
Bimage * mask_by_threshold(double threshold)
Generates a mask based on an image at a given threshold.
Definition: Bimage_mask.cpp:93
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
Bimage::mask_invert
long mask_invert()
Inverts a mask.
Definition: Bimage_mask.cpp:221
Bimage::region_assign
long region_assign(Bimage *pmask, long idx, long region_number, double threshold, int sign)
Finds all the pixels that are part of the same region.
Definition: Bimage_segment.cpp:121
Bimage::mask_combine
long mask_combine(Bimage *p, int operation)
Combines two masks with different operations.
Definition: Bimage_mask.cpp:256
Integer
Definition: utilities.h:154
Bimage::mask_dilate_erode
long mask_dilate_erode(unsigned char dir)
Dilates or erodes a binary mask.
Definition: Bimage_mask.cpp:367
Bimage::levelmask_add
long levelmask_add(Bimage *pmask, int add_level=1)
Adds a bilevel mask to a level mask.
Definition: Bimage_mask.cpp:1541
Bimage::index
long index(long nx, long ny) const
Definition: Bimage.h:383
Matrix3
Definition: Matrix3.h:17
FILL_AVERAGE
#define FILL_AVERAGE
Definition: utilities.h:173
Bimage::mask_fspace_resize
Vector3< double > mask_fspace_resize(Vector3< long > nusize)
Resizes a reciprocal space mask.
Definition: Bimage_mask.cpp:683
length2
double length2(vector< T > v)
Definition: Vector3.h:517
Bimage::mask_fspace_banded
int mask_fspace_banded(vector< double > &band)
Generate reciprocal space mask based on a specification of bands.
Definition: Bimage_mask.cpp:814
TypePointer::uc
unsigned char * uc
Definition: Bimage.h:69
SCharacter
Definition: utilities.h:150
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
Bcolumn::color
double * color()
Definition: Bplot.h:76
Bimage::variance
int variance(long kernel_size)
Calculates the local variance within the given kernel.
Definition: Bimage_stats.cpp:615
Bimage::mask_missing_cone
long mask_missing_cone(Vector3< double > origin, double mis_ang, double resolution)
Generates a mask with a missing cone.
Definition: Bimage_mask.cpp:1068
Bpage::column
Bcolumn & column(long i)
Definition: Bplot.h:110
Bimage::Bimage
Bimage()
Initializes an image.
Definition: Bimage.cpp:44
TSimple
Definition: Bimage.h:58
Bimage::levelmask_collapse
long levelmask_collapse()
Collapse a multi-level mask to a binary mask.
Definition: Bimage_mask.cpp:1503
Baxis::max
double max()
Definition: Bplot.h:32
Float
Definition: utilities.h:157
verbose
int verbose
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::real_size
Vector3< double > real_size()
Definition: Bimage.h:487
Bimage::levelmask_average_region_size
double levelmask_average_region_size()
Calculates the average size of regions in a level mask.
Definition: Bimage_mask.cpp:1809
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:256
Bimage::mask_open
long mask_open(int times=1)
Opens a binary mask.
Definition: Bimage_mask.cpp:462
M_PI
#define M_PI
Definition: utilities.h:59
Bimage::extract
Bimage * extract(long nn)
Extracts one sub-image into new image structure.
Definition: Bimage_extract.cpp:21
Bimage::maximum
double maximum()
Definition: Bimage.h:535
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
symmetry_get_all_matrices
Matrix3 * symmetry_get_all_matrices(Bsymmetry *sym, long &nsym)
Get all symmetry-related views of one given view.
Definition: symmetry.cpp:520
Vector3::scalar
double scalar(const Vector3 &v) const
Definition: Vector3.h:247
Bcolumn::number
long number()
Definition: Bplot.h:61
Bimage::apply_soft_mask
long apply_soft_mask(long nn, Bimage *pmask, int fill_type, double fill)
Applies a soft mask to a sub-image.
Definition: Bimage_mask.cpp:2330
Bimage::mask_merge_delete
long mask_merge_delete(long min_size, long min_if)
Calculates the interfaces between regions and deletes/merges small ones.
Definition: Bimage_mask.cpp:2226
Bimage::statistics
long statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Bimage::level_mask_extract
Bimage * level_mask_extract(Bimage *pmask)
Extracts all the regions associated with a multi-level mask.
Definition: Bimage_mask.cpp:1785
Vector3::angle
double angle(Vector3< T2 > &v)
Definition: Vector3.h:257
Bimage::data_assign
unsigned char * data_assign(unsigned char *nudata)
Assign image data.
Definition: Bimage.cpp:852
Bcolumn::type
long type()
Definition: Bplot.h:66
Bsub_image::FOM
double FOM()
Definition: Bimage.h:151
length
double length(vector< T > v)
Definition: Vector3.h:528
Bimage::mask_symmetrize
long mask_symmetrize(Bsymmetry *sym)
Symetrizes a mask.
Definition: Bimage_mask.cpp:621
Bpage::axis
Baxis & axis(long id)
Definition: Bplot.h:117
Bpage::title
Bstring & title()
Definition: Bplot.h:100
RGB
Definition: Color.h:24
Bimage::sum
void sum(long m, Bimage **p)
Sums an array of images with their FOM blocks.
Definition: Bimage_combine.cpp:23
Bimage::levelmask_select
long levelmask_select(Bstring &select_list)
Retains the selected levels in a multi-level mask.
Definition: Bimage_mask.cpp:1650
Bimage::levelmask_colorize
long levelmask_colorize()
Colorizes a multi-level mask with random color assignments.
Definition: Bimage_mask.cpp:1887
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bimage::variance_mask
Bimage * variance_mask(long kernel_size, double lowvar=1e-6, int bkg_flag=0)
Calculates a mask based on local variance.
Definition: Bimage_mask.cpp:1367
View::vector3
Vector3< double > vector3()
Definition: View.h:126
level
size_t level(0)
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bimage::channels
long channels()
Definition: Bimage.h:371
Bimage::mask_rectangle
long mask_rectangle(double length, double width, double rect_angle, int wrap)
Generates a mask along an axis within a 2D image.
Definition: Bimage_mask.cpp:569
Bsub_image::sampling
void sampling(double x, double y, double z)
Definition: Bimage.h:123
Bimage::mask_split
long mask_split(long voxels_per_level)
Converts a mask to a multilevel mask with a given number of voxels per level.
Definition: Bimage_mask.cpp:1453
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
Bsymmetry::label
Bstring label
Definition: symmetry.h:41
Bimage::set
void set(long j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:1096
Bsymmetry
Definition: symmetry.h:38
TRGB
Definition: Bimage.h:62
Bimage::levelmask_color_by_size
Bimage * levelmask_color_by_size()
Color a multi-level mask based on the volumes of regions.
Definition: Bimage_mask.cpp:1924
Bimage::to_mask
long to_mask()
Definition: Bimage.h:1299
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
volume
T volume(vector< T > v)
Definition: Vector3.h:545
Matrix
Definition: Matrix.h:21
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::clear
void clear()
Definition: Bimage.h:697
Bplot::page
Bpage & page(long i)
Definition: Bplot.h:211
Bit
Definition: utilities.h:148
Bimage::mask_fill
long mask_fill(Vector3< long > voxel)
Fills an empty part of a mask indicated by the given voxel.
Definition: Bimage_mask.cpp:500
Bimage::mask_erode
long mask_erode(long times=1)
Erodes a binary mask.
Definition: Bimage_mask.cpp:444
Bimage::fspace_default_bands
vector< double > fspace_default_bands(double res_lo, double res_hi)
Sets up default frequency space bands to generate a mask.
Definition: Bimage_mask.cpp:772
Vector3< long >
View
Definition: View.h:26
Bimage::mask_dilate
long mask_dilate(long times=1)
Dilates a binary mask.
Definition: Bimage_mask.cpp:424
Vector3::min
Type min()
Definition: Vector3.h:169
Bimage::mask_close
long mask_close(int times=1)
Closes a binary mask.
Definition: Bimage_mask.cpp:482
Bpage::columns
void columns(long ncol)
Definition: Bplot.h:105
RGB::spectrum
void spectrum(double value, double cmin, double cmax)
Definition: Color.h:89
Bimage::page_size
Vector3< long > page_size()
Definition: Bimage.h:480
Bimage::images
long images()
Definition: Bimage.h:491
Bimage::levelmask_size_histogram
Bplot * levelmask_size_histogram()
Color a multi-level mask based on the volumes of regions.
Definition: Bimage_mask.cpp:2018
Bimage::plot
Bplot * plot()
Converts a one-dimensional image into a plot.
Definition: Bimage.cpp:3836
Bimage::fill
void fill(double v)
Definition: Bimage.h:698
Bimage::levelmask_clean
long levelmask_clean()
Removes empty levels from a multi-level mask.
Definition: Bimage_mask.cpp:1849
Bimage::mask_missing_pyramid
long mask_missing_pyramid(Vector3< double > origin, double tilt_axis1, double tilt_axis2, double tilt_neg1, double tilt_pos1, double tilt_neg2, double tilt_pos2, double resolution)
Generates a mask with a missing pyramid.
Definition: Bimage_mask.cpp:981
Vector3::volume
double volume()
Definition: Vector3.h:235
VERB_FULL
#define VERB_FULL
Definition: utilities.h:109
Bimage::background
double background(long nn)
Definition: Bimage.h:542
Bimage::mask_missing_find
long mask_missing_find(Vector3< double > ori, double resolution, Bstring &mis_type)
Generates a missing mask from an example image.
Definition: Bimage_mask.cpp:1140
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:106
Bimage::data_type
DataType data_type()
Definition: Bimage.h:349
Bimage::variance_threshold
double variance_threshold(double lowvar)
Calculates a threshold for a local variance image.
Definition: Bimage_mask.cpp:1308
Bimage::mask_plane
long mask_plane(Vector3< double > origin, Vector3< double > normal)
Generates a mask on one side of a plane.
Definition: Bimage_mask.cpp:514
Bimage::data_size
long data_size()
Definition: Bimage.h:255
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::mask_missing_wedge
long mask_missing_wedge(Vector3< double > origin, double tilt_axis, double tilt_neg, double tilt_pos, double resolution)
Generates a mask with a missing wedge.
Definition: Bimage_mask.cpp:899
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
view_symmetry_reference
View view_symmetry_reference(Bsymmetry *sym)
Returns an asymmetric unit reference point.
Definition: symmetry.cpp:315
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
Bcolumn::axis
long axis()
Definition: Bplot.h:68
Bimage::mask_by_thresholds
Bimage * mask_by_thresholds(vector< double > threshold)
Generates a mask based on an image at a given threshold.
Definition: Bimage_mask.cpp:129
Bplot
Definition: Bplot.h:146
Bimage::tile_mask
Bimage * tile_mask(long step)
Converts a mask to a tiled multilevel mask.
Definition: Bimage_mask.cpp:1415