| Bsoft 2.0.5 Bernard's software package

Bimage_extract.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "spline.h"
11 #include "utilities.h"
12
13 // Declaration of global variables
14 extern int verbose; // Level of output to the screen
15
21 Bimage* Bimage::extract(long nn)
22 {
23 long j, k, imgsize(x*y*z*c);
24
25 Bimage* img = copy_header(1);
26 img->image[0] = image[nn];
27 img->data_alloc();
28
29 for ( j=nn*imgsize, k=0; k<imgsize; j++, k++ ) img->set(k, (*this)[j]);
30
31 return img;
32 }
33
40 Bimage* Bimage::extract(long n1, long n2)
41 {
42 if ( n1 > n2 ) swap(n1, n2);
43 if ( n1 >= n ) n1 = n-1;
44 if ( n2 >= n ) n2 = n-1;
45
46 long i, j, k, nn, ne, imgsize(x*y*z*c);
47
48 Bimage* img = copy_header(n2-n1+1);
49 img->data_alloc();
50
51 for ( ne=0, nn=n1; nn<=n2; nn++, ne++ ) {
52 img->image[ne] = image[nn];
53 for ( i=0, j=nn*imgsize, k=ne*imgsize; i<imgsize; i++, j++, k++ )
54 img->set(k, (*this)[j]);
55 }
56
57 return img;
58 }
59
69 Bimage* Bimage::extract(long nn, Vector3<long> coords, Vector3<long> size,
70 int fill_type, double fill)
71 {
72 long i, j, xx, yy, zz, cc;
73 long oldx, oldy, oldz;
74
75 Bimage* img = copy_header(1);
76 img->size(size);
77 img->image[0] = image[nn];
78 img->data_alloc();
79
80 if ( fill_type == FILL_AVERAGE ) fill = avg;
81 // else if ( fill_type == FILL_BACKGROUND ) fill = image[nn].background();
82 if ( fill_type == FILL_BACKGROUND ) fill = background(nn);
83
84 for ( zz=0, oldz=coords[2]; zz<img->z; zz++, oldz++ ) {
85 for ( yy=0, oldy=coords[1]; yy<img->y; yy++, oldy++ ) {
86 for ( xx=0, oldx=coords[0]; xx<img->x; xx++, oldx++ ) {
87 i = img->index(xx, yy, zz);
88 if ( within_boundaries(oldx, oldy, oldz) ) {
89 j = index(oldx, oldy, oldz, nn);
90 for ( cc=0; cc<c; cc++, i++, j++ ) img->set(i, (*this)[j]);
91 } else img->set(i, fill);
92 }
93 }
94 }
95
96 // img->image->origin(coords);
97 img->origin(coords);
98
99 return img;
100 }
101
111 Bimage* Bimage::extract(long nn, Vector3<double> loc, Vector3<long> size,
112 Vector3<double> ori, Matrix3 mat)
113 {
114 if ( ori[0] == 0 && ori[1] == 0 && ori[2] == 0 )
115 ori = size/2;
116
117 long i, xx, yy, zz, cc;
118 Vector3<double> v, vold;
119
120 Bimage* img = copy_header(1);
121 img->size(size);
122 img->image[0] = image[nn];
123 img->origin(ori);
124 img->data_alloc();
125
126 if ( verbose & VERB_DEBUG )
127 cout << "DEBUG Bimage::extract: size=" << size << endl;
128
129 for ( i=zz=0; zz<img->z; zz++ ) {
130 v[2] = zz - ori[2];
131 for ( yy=0; yy<img->y; yy++ ) {
132 v[1] = yy - ori[1];
133 for ( xx=0; xx<img->x; xx++ ) {
134 v[0] = xx - ori[0];
135 vold = (mat * v) + loc;
136 for ( cc=0; cc<c; cc++, i++ )
137 img->set(i, interpolate(cc, vold, nn, background(nn)));
138 }
139 }
140 }
141
142 return img;
143 }
144
154 Bimage* Bimage::extract_wrap(long nn, Vector3<double> loc, Vector3<long> size,
155 Vector3<double> ori, Matrix3 mat)
156 {
157 long i, xx, yy, zz, cc;
158 Vector3<double> v, vold;
159
160 Bimage* img = copy_header(1);
161 img->size(size);
162 img->image[0] = image[nn];
163 // img->image->origin(origin);
164 img->origin(ori);
165 img->data_alloc();
166
167 for ( i=zz=0; zz<img->z; zz++ ) {
168 v[2] = zz - ori[2];
169 for ( yy=0; yy<img->y; yy++ ) {
170 v[1] = yy - ori[1];
171 for ( xx=0; xx<img->x; xx++ ) {
172 v[0] = xx - ori[0];
173 vold = (mat * v) + loc;
174 for ( cc=0; cc<c; cc++, i++ )
175 img->set(i, interpolate_wrap(cc, vold, nn));
176 }
177 }
178 }
179
180 return img;
181 }
182
197 Bimage* Bimage::extract_shell(long nn, double minrad, double maxrad)
198 {
199 long i, j, xx, yy, zz, cc;
200 double rx2, ry2, rz2, r2;
201
202 if ( minrad > maxrad ) swap(minrad, maxrad);
203 if ( minrad < 0 ) minrad = 0;
204 if ( maxrad > x ) maxrad = x - 1;
205
206 double minrad2 = minrad*minrad;
207 double maxrad2 = maxrad*maxrad;
208
209 Bimage* pex = copy_header(1);
210 pex->image[0] = image[nn];
211 pex->data_alloc();
212 pex->fill(avg);
213
214 if ( verbose & VERB_PROCESS ) {
215 cout << "Extracting subimage: " << nn << endl;
216 cout << "Shell: " << minrad << " " << maxrad << endl;
217 cout << endl;
218 }
219
220 for ( zz=0; zz<z; zz++ ) {
221 if ( z > 1 ) {
222 rz2 = zz - image[nn].origin()[2];
223 rz2 *= rz2;
224 } else rz2 = 0;
225 for ( yy=0; yy<y; yy++ ) {
226 ry2 = yy - image[nn].origin()[1];
227 ry2 *= ry2;
228 for ( xx=0; xx<x; xx++ ) {
229 rx2 = xx - image[nn].origin()[0];
230 rx2 *= rx2;
231 r2 = rx2 + ry2 + rz2;
232 if ( r2 >= minrad2 && r2 <= maxrad2 ) {
233 i = pex->index(xx, yy, zz);
234 j = index(xx, yy, zz, nn);
235 for ( cc=0; cc<c; cc++, i++, j++ ) pex->set(i, (*this)[j]);
236 }
237 }
238 }
239 }
240
241 pex->statistics();
242
243 return pex;
244 }
245
263 vector<Vector3<long>> Bimage::tile_coordinates(Vector3<long>& start,
264 Vector3<long>& region, Vector3<long>& tile_size,
265 Vector3<long>& step_size, int exceed)
266 {
267 vector<Vector3<long>> coords;
268
269 if ( tile_size.length() < 1 ) {
270 error_show("Bimage::tile_coordinates", __FILE__, __LINE__);
271 return coords;
272 }
273
274 long i, xx, yy, zz;
275
276 if ( region.length() < 2 ) region = size();
277
278 if ( start[0] > x ) start[0] = 0;
279 if ( start[1] > y ) start[1] = 0;
280 if ( start[2] > z ) start[2] = 0;
281
282 if ( region[0] > x - start[0] ) region[0] = x - start[0];
283 if ( region[1] > y - start[1] ) region[1] = y - start[1];
284 if ( region[2] > z - start[2] ) region[2] = z - start[2];
285
286 tile_size = tile_size.min(region);
287
288 if ( step_size[0] <= 0 ) step_size[0] = tile_size[0];
289 if ( step_size[1] <= 0 ) step_size[1] = tile_size[1];
290 if ( step_size[2] <= 0 ) step_size[2] = tile_size[2];
291
292 if ( !exceed ) region -= tile_size - 1;
293
294 // calculate_background();
295
296 // Count the number of tiles to be extracted
297 long ntiles(0);
298 for ( zz=0; zz<region[2]; zz+=step_size[2] )
299 for ( yy=0; yy<region[1]; yy+=step_size[1] )
300 for ( xx=0; xx<region[0]; xx+=step_size[0] )
301 ntiles++;
302
303 coords.resize(ntiles);
304
305 for ( i=zz=0; zz<region[2]; zz+=step_size[2] )
306 for ( yy=0; yy<region[1]; yy+=step_size[1] )
307 for ( xx=0; xx<region[0]; xx+=step_size[0], i++ )
308 coords[i] = Vector3<long>(xx + start[0], yy + start[1], zz + start[2]);
309
310 if ( verbose & VERB_PROCESS ) {
311 cout << "Generating " << ntiles << " tile coordinates:" << endl;
312 cout << "Start: " << start << endl;
313 cout << "Tile size: " << tile_size << endl;
314 cout << "Step size: " << step_size << endl;
315 cout << endl;
316 }
317
318 return coords;
319 }
320
335 Bimage* Bimage::extract_tiles(long nn, vector<Vector3<long>>& coords, Vector3<long> tile_size)
336 {
337 if ( tile_size.length() < 1 ) {
338 error_show("Bimage::extract_tiles", __FILE__, __LINE__);
339 cerr << "Error: Size of subimage is less than one!" << endl;
340 return NULL;
341 }
342
343 tile_size = tile_size.min(size());
344
345 if ( nn >= n ) nn = n - 1;
346
347 long ntiles(coords.size());
348 Bimage* pex = copy_header(ntiles);
349
350 pex->size(tile_size);
351 pex->page_size(tile_size);
352
353 pex->data_alloc();
354 pex->fill(avg);
355
356 if ( verbose & VERB_FULL ) {
357 cout << "Extracting " << pex->images() << " tiles using coordinates:" << endl;
358 cout << "Tile size: " << pex->size() << endl;
359 cout << endl;
360 }
361
362 #ifdef HAVE_GCD
363 dispatch_apply(ntiles, dispatch_get_global_queue(0, 0), ^(size_t nex){
364 Bimage* pt = extract(nn, coords[nex], tile_size, FILL_BACKGROUND);
365 pex->replace(nex, pt);
366 delete pt;
367 });
368 #else
369 #pragma omp parallel for
370 for ( long nex=0; nex<ntiles; nex++ ) {
371 Bimage* pt = extract(nn, coords[nex], tile_size, FILL_BACKGROUND);
372 pex->replace(nex, pt);
373 delete pt;
374 }
375 #endif
376
377 pex->statistics();
378
379 return pex;
380 }
381
382
401 Bimage* Bimage::extract_tiles(long nn, Vector3<long> start,
402 Vector3<long> region, Vector3<long> tile_size,
403 Vector3<long> step_size, int exceed)
404 {
405 vector<Vector3<long>> coords = tile_coordinates(start, region, tile_size, step_size, exceed);
406
407 if ( verbose & VERB_FULL )
408 cout << "Extracting " << coords.size() << " tiles:" << endl << endl;
409
410 Bimage* pex = extract_tiles(nn, coords, tile_size);
411
412 return pex;
413 }
414
415 long find_optimal_tiling(long target, long tile_size, double fraction=0.2)
416 {
417 if ( fraction > 0.5 ) fraction = 0.5;
418
419 long overlap(fraction*tile_size), i, imin(overlap/2), imax(overlap*2);
420 long step(tile_size - overlap);
421 long num(target/step);
422 long d, dmin(target);
423
424 for ( i = imin; i < imax; i++ ) {
425 step = tile_size - i;
426 num = target/step;
427 d = num*step + i - target;
428 if ( d >= 0 && dmin > d ) {
429 overlap = i;
430 dmin = d;
431 if ( verbose & VERB_FULL )
432 cout << overlap << tab << num << tab << step << tab << d << endl;
433 }
434 }
435
436 return overlap;
437 }
438
453 Bimage* Bimage::extract_tiles(long nn, Vector3<long> tile_size, double fraction)
454 {
455 tile_size = tile_size.min(size());
456
457 Vector3<long> num, overlap, step, icoor;
458 Vector3<long> maxori(size() - tile_size);
459
460 for ( long j=0; j<3; j++ )
461 if ( size()[j] > 1 ) overlap[j] = find_optimal_tiling(size()[j], tile_size[j], fraction);
462
463 step = tile_size - overlap;
464
465 num = size()/step;
466 num = num.max(1);
467
468 if ( verbose & VERB_FULL ) {
469 cout << size() << endl;
470 cout << num * step + overlap << endl;
471 }
472
473 long i, ntiles(num.volume());
474
475 vector<Vector3<long>> coords(ntiles);
476
477 for ( i=icoor[2]=0; icoor[2]<num[2]; icoor[2]++ )
478 for ( icoor[1]=0; icoor[1]<num[1]; icoor[1]++ )
479 for ( icoor[0]=0; icoor[0]<num[0]; icoor[0]++, i++ ) {
480 coords[i] = icoor * step;
481 coords[i] = coords[i].min(maxori);
482 }
483
484
485 if ( verbose & VERB_PROCESS ) {
486 cout << "Extracting " << ntiles << " tiles:" << endl;
487 cout << "Tile size: " << tile_size << endl;
488 cout << "Number of tiles: " << num << endl;
489 cout << "Overlap: " << overlap << endl << endl;
490 }
491
492 Bimage* pex = extract_tiles(nn, coords, tile_size);
493
494 return pex;
495 }
496
509 Bimage* Bimage::extract_line(long nn, Vector3<double> start, Vector3<double> end, long width)
510 {
511 if ( width < 1 ) width = 1;
512
513 long i, j, wh(width/2);
514 Vector3<double> vec(end - start), vecp, coor;
515 long len(vec.length() + 1);
516
517 vec.normalize();
518 vecp = Vector3<double>(vec[1], vec[0], vec[2]);
519
520 Bimage* pline = new Bimage(Float, TSimple, len, 1, 1, 1);
521
522 for ( i=0; i<len; i++ ) {
523 coor = start + vec*i;
524 for ( j=-wh; j<=wh; j++ )
525 pline->add(i, interpolate(coor + vecp*j, nn));
526 pline->set(i, (*pline)[i]/width);
527 }
528
529 pline->statistics();
530
531 return pline;
532 }
533
546 Bimage* Bimage::extract_tetrahedron(Vector3<double>* tet, int fill_type, double fill)
547 {
548 if ( fill_type == FILL_AVERAGE ) fill = avg;
549
550 long i, j, k, nn, xx, yy, zz, cc;
551
552 Vector3<double> center;
553 Vector3<double> normal[4];
554 double origin[4];
555
556 for ( i=0; i<4; i++ ) center = center + tet[i];
557 center /= 4.0;
558
559 normal[0] = tet[0].normal(tet[1], tet[2]);
560 normal[1] = tet[1].normal(tet[2], tet[3]);
561 normal[2] = tet[2].normal(tet[3], tet[0]);
562 normal[3] = tet[3].normal(tet[0], tet[1]);
563
564 // The distance of a point from a plane is given by the inner product sum of
565 // the normal to the plane and the vector from that point to any point on the plane
566 for ( i=0; i<4; i++ ) {
567 origin[i] = normal[i].scalar(tet[i]);
568 if ( normal[i].scalar(center) < origin[i] ) {
569 normal[i] = -normal[i];
570 origin[i] = -origin[i];
571 }
572 }
573
574 Bimage* ptet = copy();
575
576 if ( verbose & VERB_PROCESS ) {
577 cout << "Extracting a tetrahedron:" << endl;
578 cout << "Vertices: " << tet[0] << endl;
579 cout << " " << tet[1] << endl;
580 cout << " " << tet[2] << endl;
581 cout << " " << tet[3] << endl;
582 cout << "Center: " << center << endl;
583 cout << "Normals: " << normal[0] << " (" << origin[0] << ")" << endl;
584 cout << " " << normal[1] << " (" << origin[1] << ")" << endl;
585 cout << " " << normal[2] << " (" << origin[2] << ")" << endl;
586 cout << " " << normal[3] << " (" << origin[3] << ")" << endl;
587 cout << endl;
588 } else if ( verbose & VERB_LABEL )
589 cout << "Extracting a tetrahedron" << endl << endl;
590
591 for ( i=nn=0; nn<n; nn++ ) {
592 if ( fill_type == FILL_BACKGROUND ) fill = background(nn);
593 for ( zz=0; zz<z; zz++ ) {
594 for ( yy=0; yy<y; yy++ ) {
595 for ( xx=0; xx<x; xx++, i++ ) {
596 for ( j=0; j<4; j++ ) {
597 if ( normal[j][0]*xx + normal[j][1]*yy + normal[j][2]*zz < origin[j] )
598 for ( cc=0, k=i*c; cc<c; cc++, k++ )
599 ptet->set(k, fill);
600 }
601 }
602 }
603 }
604 }
605
606 return 0;
607 }
608
620 Bimage* Bimage::orthogonal_slices(long nn, Vector3<long> voxel,
621 Vector3<long> ext_size)
622 {
623 if ( voxel[0] < 0 || voxel[1] < 0 || voxel[2] < 0 ) return NULL;
624 if ( voxel[0] >= x || voxel[1] >= y || voxel[2] >= z ) return NULL;
625
626 if ( ext_size.volume() < 1 ) ext_size = size();
627
628 int xf, yf;
629 long i, j, iy, xx, yy, zz, cc;
630 long xo, yo, zo;
631 long h, nh(1);
632 if ( z > 1 ) nh = 3;
633 long nx = (long) (ext_size[0]);
634 long ny = (long) (ext_size[1]);
635
636 Vector3<long> start(voxel - (ext_size * 0.5));
637 Vector3<long> end(start + ext_size);
638 Vector3<double> ori;
639
640 if ( verbose & VERB_PROCESS ) {
641 cout << "Extracting orthogonal views:" << endl;
642 cout << "Start: " << start << endl;
643 cout << "End: " << end << endl;
644 cout << "Fill value: " << image[nn].background() << endl;
645 cout << endl;
646 }
647
648 Bimage* porth = new Bimage(datatype, compoundtype, nx, ny, 1, nh);
649 porth->sampling(sampling());
650 porth->fill(image[nn].background());
651
652 for ( h=0; h<nh; h++ ) {
653 porth->background(h, background(nn));
654 if ( h%2 == 0 ) ori[0] = image[nn].origin()[0] - start[0];
655 else ori[0] = image[nn].origin()[2] - start[2];
656 if ( h < 2 ) ori[1] = image[nn].origin()[1] - start[1];
657 else ori[1] = image[nn].origin()[2] - start[2];
658 porth->origin(h, ori);
659 if ( h == 0 ) porth->image[h].view(0,0,1,0);
660 else if ( h == 1 ) porth->image[h].view(1,0,0,0);
661 else porth->image[h].view(0,1,0,0);
662 xo = voxel[0];
663 yo = voxel[1];
664 zo = voxel[2];
665 for ( yy=0; yy<ny; yy++ ) {
666 yf = 1;
667 if ( h < 2 ) {
668 yo = (long) (yy + start[1]);
669 if ( yo < 0 ) yf = 0;
670 else if ( yo >= y ) yf = 0;
671 } else {
672 zz = yy;
673 zo = (long) (zz + start[2]);
674 if ( zo < 0 ) yf = 0;
675 else if ( zo >= z ) yf = 0;
676 }
677 iy = (h*ny + yy)*nx;
678 for ( xx=0; xx<nx; xx++ ) {
679 xf = 1;
680 if ( h%2 == 0 ) {
681 xo = (long) (xx + start[0]);
682 if ( xo < 0 ) xf = 0;
683 else if ( xo >= x ) xf = 0;
684 } else {
685 zz = xx;
686 zo = (long) (zz + start[2]);
687 if ( zo < 0 ) xf = 0;
688 else if ( zo >= z ) xf = 0;
689 }
690 i = (iy + xx)*porth->c;
691 if ( xf && yf ) {
692 j = index(xo, yo, zo, nn);
693 for ( cc=0; cc<porth->c; cc++, i++, j++ ) porth->set(i, (*this)[j]);
694 }
695 }
696 }
697 }
698
699 porth->statistics();
700
701 return porth;
702 }
703
704 int Bimage::extract_show_chunk(Bimage* pshow, int aflag, long i, long len)
705 {
706 long nn(sn);
707 long zz(sz);
708 double scale(ss);
709
710 if ( compoundtype == TComplex ) {
711 zz += z/2;
712 if ( zz >= z ) zz -= z;
713 }
714
715 if ( scale >= 1 ) aflag = 0; // No averaging for enlargements
716
717 int threshold(0);
718 if ( fabs(smax - smin) < 1e-37 ) threshold = 1;
719
720 long ic, j, jz, xx, yy, cc, m, xm(x/2), ym(y/2);
721 long xo, yo;
722 double xf, yf;
723 double iscale(1.0/scale), shift = (scale < 1)? (iscale - 1)/2: 0;
724
725 double* value = new double[c];
726 double dispval[4];
727 double dscale = 255.0/(smax - smin);
728 long ds(pshow->x*pshow->y);
729 RGB<double> rgb;
730 CMYK<double> cmyk;
731
732 // Note that the y-axis is flipped
733 xx = i%pshow->x;
734 yy = i/pshow->x;
735 jz = (nn*z + zz)*y;
736
737 m = i+len;
738 if ( m > ds ) m = ds;
739 for ( ; i<m; i++, xx++ ) {
740 if ( xx >= pshow->x ) {
741 xx = 0;
742 yy++;
743 }
744 if ( compoundtype == TComplex ) {
745 xf = xx*iscale - xm;
746 yf = (pshow->y - yy - 1)*iscale - ym;
747 if ( xf < 0 ) xf += x;
748 if ( yf < 0 ) yf += y;
749 } else {
750 xf = xx*iscale;
751 yf = (pshow->y - yy - 1)*iscale;
752 }
753 if ( xf >= 0 || xf <= x-1 || yf >=0 || yf <= y-1 ) {
754 yo = (long) (yf + shift);
755 xo = (long) (xf + shift);
756 if ( datatype == Bit ) {
757 j = (jz + yo)*page_size()[0] + xo;
758 pshow->set(i, 255 * (*this)[j]);
759 if ( dscale < 0 ) pshow->set(i, 255 - (*pshow)[i]);
760 } else {
761 if ( aflag ) {
762 for ( cc=0; cc<c; cc++ ) value[cc] = average2D(cc, xf, yf, zz, nn, iscale);
763 } else {
764 for ( j = ((jz + yo)*x + xo)*c, cc=0; cc<c; cc++, j++ )
765 value[cc] = (*this)[j];
766 }
767 if ( compoundtype == TComplex ) {
768 dispval[0] = value[0]*value[0] + value[1]*value[1];
769 } else if ( compoundtype == TCMYK ) {
770 if ( datatype == UCharacter ) for ( cc=0; cc<4; cc++ ) value[cc] /= 255;
771 cmyk = CMYK<double>(value);
772 rgb = RGB<double>(cmyk);
773 for ( cc=0; cc<3; cc++ ) dispval[cc] = 255*rgb[cc];
774 } else {
775 for ( cc=0; cc<pshow->c; cc++ ) dispval[cc] = value[cc];
776 }
777 if ( threshold ) {
778 for ( cc=0; cc<pshow->c && cc<3; cc++ ) {
779 if ( dispval[cc] > smin ) dispval[cc] = 255;
780 else dispval[cc] = 0;
781 }
782 } else {
783 for ( cc=0; cc<pshow->c; cc++ ) {
784 if ( cc < 3 ) dispval[cc] = floor(dscale*(dispval[cc]-smin)+0.5);
785 if ( dispval[cc] > 255 ) dispval[cc] = 255;
786 else if ( dispval[cc] < 0 ) dispval[cc] = 0;
787 }
788 }
789 // cout << dispval[3] << tab;
790 if ( pshow->c > 3 ) dispval[3] = 255;
791 // if ( dispval[3] > 100 ) dispval[3] = 255;
792 for ( cc=0, ic = i*pshow->c; cc<pshow->c; cc++, ic++ )
793 pshow->set(ic, dispval[cc]);
794 }
795 }
796 }
797 // cout << endl;
798
799 delete [] value;
800
801 return 0;
802 }
803
820 Bimage* Bimage::extract_show(int aflag)
821 {
822 CompoundType ctype;
823
824 switch ( compoundtype ) {
825 case TSimple: ctype = TSimple; break;
826 case TComplex: ctype = TSimple; break;
827 case TVector3:
828 case TCMYK:
829 case TRGB: ctype = TRGB; break;
830 case TView:
831 case TRGBA: ctype = TRGBA; break;
832 default: ctype = compoundtype;
833 }
834
835 Bimage* pshow = new Bimage(UCharacter, ctype,
836 (long) (ss*x), (long) (ss*y), 1, 1);
837 pshow->sampling(sampling()/ss);
838
839 long ds = pshow->x*pshow->y;
840 // long chunk_size = get_chunk_size(ds, c);
841 long chunk_size = get_chunk_size(ds);
842
843 #ifdef HAVE_GCD
844 dispatch_apply((ds - 1)/chunk_size + 1, dispatch_get_global_queue(0, 0), ^(size_t i){
845 extract_show_chunk(pshow, aflag, i*chunk_size, chunk_size);
846 });
847 #else
848 #pragma omp parallel for
849 for ( long i=0; i<ds; i+=chunk_size )
850 extract_show_chunk(pshow, aflag, i, chunk_size);
851 #endif
852
853 return pshow;
854 }
855
856
876 Bimage* Bimage::extract_magnify(long nn, Vector3<long> center,
877 Vector3<long> ext_size, double scale)
878 {
879 if ( compoundtype == TComplex ) {
880 center = vector3_set_PBC(center - size()/2, size());
881 } else {
882 if ( center[0] < 0 || center[1] < 0 || center[2] < 0 ) return NULL;
883 if ( center[0] >= x || center[1] >= y || center[2] >= z ) return NULL;
884 }
885
886 int threshold(0), xf, yf;
887 if ( fabs(smax - smin) < 1e-37 ) threshold = 1;
888
889 long i, j, iy, jz, xx, yy, zz, cc;
890 long xo, yo, zo;
891 long h, nh(1);
892 if ( z > 1 ) nh = 3;
893 long nx = (long) (scale*ext_size[0]);
894 long ny = (long) (scale*ext_size[1]);
895 double iscalex = 1.0/scale;
896 double iscaley = 1.0/scale;
897 double iscalez = 1.0/scale;
898 RGB<double> rgb;
899 CMYK<double> cmyk;
900
901 Vector3<long> start = center - (ext_size * 0.5);
902 Vector3<long> end = start + ext_size;
903
904 if ( verbose & VERB_DEBUG ) {
905 cout << "DEBUG Bimage::extract_magnify: start=" << start << endl;
906 cout << "DEBUG Bimage::extract_magnify: end=" << end << endl;
907 cout << "DEBUG Bimage::extract_magnify: size: nx=" << nx << " ny=" << ny << " c=" << c << endl;
908 }
909
910 CompoundType ctype;
911
912 switch ( compoundtype ) {
913 case TSimple: ctype = TSimple; break;
914 case TComplex: ctype = TSimple; break;
915 case TVector3:
916 case TCMYK:
917 case TRGB: ctype = TRGB; break;
918 case TView:
919 case TRGBA: ctype = TRGBA; break;
920 default: ctype = compoundtype;
921 }
922
923 Bimage* pmag = new Bimage(UCharacter, ctype, nx, ny, 1, nh);
924 pmag->sampling(sampling()/scale);
925
926 double* value = new double[c];
927 double dispval[4];
928
929 double dscale = 255.0/(smax - smin);
930
931 // Note that the y-axis is flipped
932 for ( h=0; h<nh; h++ ) {
933 xo = center[0];
934 yo = center[1];
935 zo = center[2];
936 for ( yy=0; yy<ny; yy++ ) {
937 yf = 1;
938 if ( h < 2 ) {
939 yo = (long) (yy*iscaley + start[1]);
940 if ( compoundtype == TComplex ) {
941 if ( yo < 0 ) yo += y;
942 else if ( yo >= y ) yo -= y;
943 } else {
944 if ( yo < 0 ) yf = 0;
945 else if ( yo >= y ) yf = 0;
946 }
947 } else {
948 zz = yy;
949 zo = (long) (zz*iscalez + start[2]);
950 if ( compoundtype == TComplex ) {
951 if ( zo < 0 ) zo += z;
952 else if ( zo >= z ) yo -= z;
953 } else {
954 if ( zo < 0 ) yf = 0;
955 else if ( zo >= z ) yf = 0;
956 }
957 }
958 iy = (h*ny + ny - 1 - yy)*nx;
959 for ( xx=0; xx<nx; xx++ ) {
960 xf = 1;
961 if ( h%2 == 0 ) {
962 xo = (long) (xx*iscalex + start[0]);
963 if ( compoundtype == TComplex ) {
964 if ( xo < 0 ) xo += x;
965 else if ( xo >= x ) xo -= x;
966 } else {
967 if ( xo < 0 ) xf = 0;
968 else if ( xo >= x ) xf = 0;
969 }
970 } else {
971 zz = xx;
972 zo = (long) (zz*iscalez + start[2]);
973 if ( compoundtype == TComplex ) {
974 if ( zo < 0 ) zo += z;
975 else if ( zo >= z ) zo -= z;
976 } else {
977 if ( zo < 0 ) xf = 0;
978 else if ( zo >= z ) xf = 0;
979 }
980 }
981 if ( xf && yf ) {
982 i = (iy + xx)*pmag->c;
983 jz = (nn*z + zo)*y;
984 if ( datatype == Bit ) {
985 j = (jz + yo)*page_size()[0] + xo;
986 pmag->set(i, 255 * (*this)[j]);
987 if ( dscale < 0 ) pmag->set(i, 255 - (*pmag)[i]);
988 } else {
989 j = ((jz + yo)*x + xo)*c;
990 for ( cc=0; cc<c; cc++, j++ ) value[cc] = (*this)[j];
991 if ( compoundtype == TComplex ) {
992 dispval[0] = value[0]*value[0] + value[1]*value[1];
993 } else if ( compoundtype == TCMYK ) {
994 if ( datatype == UCharacter ) for ( cc=0; cc<4; cc++ ) value[cc] /= 255;
995 cmyk = CMYK<double>(value);
996 rgb = RGB<double>(cmyk);
997 for ( cc=0; cc<3; cc++ ) dispval[cc] = 255*rgb[cc];
998 } else {
999 for ( cc=0; cc<pmag->c; cc++ ) dispval[cc] = value[cc];
1000 }
1001 if ( threshold ) {
1002 for ( cc=0; cc<pmag->c; cc++ ) {
1003 if ( dispval[cc] > smin ) dispval[cc] = 255;
1004 else dispval[cc] = 0;
1005 }
1006 } else {
1007 for ( cc=0; cc<pmag->c; cc++ ) {
1008 dispval[cc] = floor(dscale*(dispval[cc]-smin)+0.5);
1009 if ( dispval[cc] > 255 ) dispval[cc] = 255;
1010 else if ( dispval[cc] < 0 ) dispval[cc] = 0;
1011 }
1012 }
1013 for ( cc=0; cc<pmag->c; cc++, i++ ) pmag->set(i, dispval[cc]);
1014 }
1015 }
1016 }
1017 }
1018 }
1019
1020 delete [] value;
1021
1022 return pmag;
1023 }
1024
1040 Bimage* Bimage::extract_slice(long nz)
1041 {
1042 int threshold(0);
1043 if ( fabs(smax - smin) < 1e-37 ) threshold = 1;
1044
1045 long i, j, xx, yy, cc, nn;
1046 RGB<double> rgb;
1047 CMYK<double> cmyk;
1048
1049 if ( verbose & VERB_DEBUG )
1050 cout << "DEBUG Bimage::extract_slice: nz=" << nz << endl;
1051
1052 CompoundType ctype;
1053
1054 switch ( compoundtype ) {
1055 case TSimple: ctype = TSimple; break;
1056 case TComplex: ctype = TSimple; break;
1057 case TVector3:
1058 case TCMYK:
1059 case TRGB: ctype = TRGB; break;
1060 case TView:
1061 case TRGBA: ctype = TRGBA; break;
1062 default: ctype = compoundtype;
1063 }
1064
1065 Bimage* pslice = new Bimage(UCharacter, ctype, x, y, 1, n);
1066 pslice->sampling(sampling());
1067
1068 double* value = new double[c];
1069 double dispval[4];
1070
1071 double dscale = 255.0/(smax - smin);
1072
1073 if ( verbose & VERB_DEBUG )
1074 cout << "DEBUG Bimage::extract_slice: dscale=" << dscale << endl;
1075
1076 // Note that the y-axis is flipped
1077 for ( i=nn=0; nn<n; nn++ ) {
1078 j = (nn*z + nz)*x*y*c;
1079 for ( yy=0; yy<y; yy++ ) {
1080 for ( xx=0; xx<x; xx++ ) {
1081 if ( datatype == Bit ) {
1082 j *= page_size()[0];
1083 pslice->set(i, 255 * (*this)[j]);
1084 if ( dscale < 0 ) pslice->set(i, 255 - (*pslice)[i]);
1085 } else {
1086 for ( cc=0; cc<c; cc++, j++ ) value[cc] = (*this)[j];
1087 if ( compoundtype == TComplex ) {
1088 dispval[0] = value[0]*value[0] + value[1]*value[1];
1089 } else if ( compoundtype == TCMYK ) {
1090 if ( datatype == UCharacter ) for ( cc=0; cc<4; cc++ ) value[cc] /= 255;
1091 cmyk = CMYK<double>(value);
1092 rgb = RGB<double>(cmyk);
1093 for ( cc=0; cc<3; cc++ ) dispval[cc] = 255*rgb[cc];
1094 } else {
1095 for ( cc=0; cc<pslice->c; cc++ ) dispval[cc] = value[cc];
1096 }
1097 if ( threshold ) {
1098 for ( cc=0; cc<pslice->c; cc++ ) {
1099 if ( dispval[cc] > smin ) dispval[cc] = 255;
1100 else dispval[cc] = 0;
1101 }
1102 } else {
1103 for ( cc=0; cc<pslice->c; cc++ ) {
1104 dispval[cc] = floor(dscale*(dispval[cc]-smin)+0.5);
1105 if ( dispval[cc] > 255 ) dispval[cc] = 255;
1106 else if ( dispval[cc] < 0 ) dispval[cc] = 0;
1107 }
1108 }
1109 for ( cc=0; cc<pslice->c; cc++, i++ ) pslice->set(i, dispval[cc]);
1110 }
1111 }
1112 }
1113 }
1114
1115 delete [] value;
1116
1117 return pslice;
1118 }
1119
1132 Bimage* Bimage::extract_filament(long img_num, double width,
1133 int axis, long nspline, Vector3<double>* spline)
1134 {
1135 if ( !d.uc ) return NULL;
1136 if ( nspline < 1 ) return NULL;
1137
1138 if ( axis < 1 || axis > 3 ) { // Default axis selection
1139 if ( z > 1 ) axis = 3;
1140 else axis = 1;
1141 }
1142
1143 Vector3<long> filsize((long)width, (long)width, (long)width);
1144 filsize[axis-1] = nspline;
1145 filsize = filsize.min(size());
1146
1147 Bimage* pfil = new Bimage(Float, compoundtype, filsize, 1);
1148 pfil->sampling(sampling());
1149 pfil->label(label());
1150
1151 long i, xx, yy, zz, s(0);
1152 double w, halfwidth(width/2);
1153 Vector3<double> vref, v, vf;
1154 Matrix3 mat(1);
1155
1156 vref[axis-1] = 1;
1157
1158 if ( verbose & VERB_DEBUG ) {
1159 cout << "DEBUG Bimage:extract_filament: img_num=" << img_num << " width=" << width << " nspline=" << nspline << endl;
1160 cout << "DEBUG Bimage:extract_filament: axis=" << axis << " size=" << filsize << endl;
1161 }
1162
1163 for ( i=zz=0; zz<pfil->z; zz++ ) {
1164 if ( axis == 3 ) s = zz;
1165 else if ( pfil->z > 1 ) vf[2] = zz - halfwidth;
1166 for ( yy=0; yy<pfil->y; yy++ ) {
1167 if ( axis == 2 ) s = yy;
1168 else if ( pfil->y > 1 ) vf[1] = yy - halfwidth;
1169 for ( xx=0; xx<pfil->x; xx++, i++ ) {
1170 if ( axis == 1 ) s = xx;
1171 else if ( pfil->x > 1 ) vf[0] = xx - halfwidth;
1172 if ( s < nspline ) {
1173 if ( s > 0 ) v = spline[s] - spline[s-1];
1174 else v = spline[1] - spline[0];
1175 v.normalize();
1176 mat = Matrix3(vref, v);
1177 // cout << mat << endl;
1178 v = mat * vf;
1179 v += spline[s];
1180 w = interpolate(v, img_num, background(img_num));
1181 pfil->add(i, w);
1182 }
1183 }
1184 }
1185 }
1186
1187 return pfil;
1188 }
1189
Bimage::extract_tiles
Bimage * extract_tiles(long nn, vector< Vector3< long >> &coords, Vector3< long > tile_size)
Extracts a set of tiles at specified positions from an image into a new image.
Definition: Bimage_extract.cpp:335
verbose
int verbose
Bimage::extract_slice
Bimage * extract_slice(long nz)
Extracts a given slice or slices from an image.
Definition: Bimage_extract.cpp:1040
Vector3::normal
Vector3 normal(Vector3 &v1, Vector3 &v2)
Definition: Vector3.h:267
Bimage::copy_header
Bimage * copy_header()
Definition: Bimage.h:650
FILL_BACKGROUND
#define FILL_BACKGROUND
Definition: utilities.h:174
Vector3::normalize
double normalize()
Definition: Vector3.h:236
Bsub_image::view
void view(double x, double y, double z, double a)
Definition: Bimage.h:143
Bimage.h
Header file for image class.
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Vector3::length
double length()
Definition: Vector3.h:222
Bimage::add
void add(long j, double v)
Definition: Bimage.h:308
vector3_set_PBC
Vector3< T1 > vector3_set_PBC(Vector3< T1 > coord, Vector3< T2 > box)
Definition: Vector3.h:682
spline.h
Header file for spline interpolation.
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:112
TView
Definition: Bimage.h:61
Bsub_image::background
double background()
Definition: Bimage.h:121
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::within_boundaries
bool within_boundaries(Vector3< double > loc)
Definition: Bimage.h:448
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
get_chunk_size
size_t get_chunk_size(size_t datasize)
Returns the chunk size per thread.
Definition: utilities.cpp:645
TypePointer::uc
unsigned char * uc
Definition: Bimage.h:69
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:107
Bimage::extract_magnify
Bimage * extract_magnify(long nn, Vector3< long > center, Vector3< long > ext_size, double scale)
Extracts a region from an image to magnify.
Definition: Bimage_extract.cpp:876
TComplex
Definition: Bimage.h:59
Bimage::Bimage
Bimage()
Initializes an image.
Definition: Bimage.cpp:44
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
TCMYK
Definition: Bimage.h:64
Bimage::tile_coordinates
vector< Vector3< long > > tile_coordinates(Vector3< long > &start, Vector3< long > &region, Vector3< long > &tile_size, Vector3< long > &step_size, int exceed)
Generates a set of tile coordinates for an image.
Definition: Bimage_extract.cpp:263
Bimage::extract_filament
Bimage * extract_filament(long img_num, double width, int axis, long nspline, Vector3< double > *spline)
Extracts a filament defined by a series of coordinates.
Definition: Bimage_extract.cpp:1132
TVector3
Definition: Bimage.h:60
TSimple
Definition: Bimage.h:58
Float
Definition: utilities.h:157
Vector3::max
Type max()
Definition: Vector3.h:175
Bimage
General image parameter class.
Definition: Bimage.h:163
scalar
double scalar(vector< T1 > &v1, vector< T2 > &v2)
Definition: Vector3.h:611
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:256
Bimage::extract_line
Bimage * extract_line(long nn, Vector3< double > start, Vector3< double > end, long width)
Extracts a line from an image into a new image.
Definition: Bimage_extract.cpp:509
Bimage::extract
Bimage * extract(long nn)
Extracts one sub-image into new image structure.
Definition: Bimage_extract.cpp:21
Bimage::shift
int shift(Vector3< double > vec, int fill_type=0, double fill=0)
Shifts an image.
Definition: Bimage_transform.cpp:587
CompoundType
CompoundType
Compound data type specifier.
Definition: Bimage.h:57
Vector3::scalar
double scalar(const Vector3 &v) const
Definition: Vector3.h:247
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
Bimage::label
void label(string s)
Definition: Bimage.h:235
RGB
Definition: Color.h:24
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
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
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bimage::rgb
RGB< double > rgb(long j)
Returns a color value at the given index.
Definition: Bimage.cpp:1033
Bimage::label
string & label()
Definition: Bimage.h:236
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::extract_tetrahedron
Bimage * extract_tetrahedron(Vector3< double > *tet, int fill_type=0, double fill=0)
Extracts a tetrahedral part of the image.
Definition: Bimage_extract.cpp:546
find_optimal_tiling
long find_optimal_tiling(long target, long tile_size, double fraction=0.2)
Definition: Bimage_extract.cpp:415
Bimage::extract_wrap
Bimage * extract_wrap(long nn, Vector3< double > loc, Vector3< long > size, Vector3< double > origin, Matrix3 mat)
Extracts a region of one sub-image into new image structure with wrapping.
Definition: Bimage_extract.cpp:154
UCharacter
Definition: utilities.h:149
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2695
Bit
Definition: utilities.h:148
Vector3< long >
Bimage::extract_show_chunk
int extract_show_chunk(Bimage *pshow, int aflag, long i, long len)
Definition: Bimage_extract.cpp:704
Bimage::orthogonal_slices
Bimage * orthogonal_slices(long nn, Vector3< long > voxel, Vector3< long > ext_size)
Extracts orthogonal views around a voxel.
Definition: Bimage_extract.cpp:620
Vector3::min
Type min()
Definition: Vector3.h:169
Bimage::extract_show
Bimage * extract_show(int aflag)
Converts a slice from an image to a 2D plane for display.
Definition: Bimage_extract.cpp:820
Bimage::center
int center(int fill_type=0, double fill=0)
Centers an image.
Definition: Bimage_transform.cpp:699
TRGBA
Definition: Bimage.h:63
Bimage::page_size
Vector3< long > page_size()
Definition: Bimage.h:480
Bimage::fill
void fill(double v)
Definition: Bimage.h:698
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
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:106
CMYK
Definition: Color.h:12
error_show
int error_show(string message, string file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:755
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::extract_shell
Bimage * extract_shell(long nn, double minrad, double maxrad)
Extracts a shell from an image into a new image.
Definition: Bimage_extract.cpp:197
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563