| Bsoft 1.9 Bernard's software package

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
img_extract.cpp
Go to the documentation of this file.
1
9 #include "rwimg.h"
10 #include "img_extract.h"
11 #include "img_edit.h"
12 #include "Matrix3.h"
13 #include "Complex.h"
14 #include "spline.h"
15 #include "Color.h"
16 #include "utilities.h"
17
18 // Declaration of global variables
19 extern int verbose; // Level of output to the screen
20
21 // Internal function prototype
22 Bimage* img_extract_bitmap(Bimage* p, int img_number, Vector3<float> start, Vector3<int> size);
23
35 Bimage* img_extract(Bimage* p, int img_number)
36 {
37 Vector3<int> size(p->size());
38 Vector3<float> start;
39
40 Bimage* pex = img_extract(p, img_number, start, size);
41
42 pex->image[0] = p->image[img_number];
43
44 return pex;
45 }
46
62 Bimage* img_extract(Bimage* p, int img_number, Vector3<float> start, Vector3<int> size)
63 {
64 if ( !p->data_pointer() ) return NULL;
65
66 if ( size.volume() < 1 ) {
67 error_show("img_extract", __FILE__, __LINE__);
68 cerr << "Error: Size of subimage is less than one!" << endl;
69 return NULL;
70 }
71
72 if ( p->data_type() == Bit ) {
73 Bimage* pex = img_extract_bitmap(p, img_number, start, size);
74 return pex;
75 }
76
77 unsigned long i, j, iy, iz, jy, jz;
78 unsigned long x, y, z, n, c, new_nimg;
79 long oldn, oldx, oldy, oldz;
80
81 if ( img_number < 0 ) {
82 new_nimg = p->images();
83 img_number = 0;
84 } else {
85 new_nimg = 1;
86 if ( img_number >= p->images() ) img_number = p->images() - 1;
87 }
88
89 Bimage* pex = p->copy_header(new_nimg);
90
91 pex->size(size);
92 pex->page_size(size);
93 pex->channels(p->channels());
94 pex->data_alloc();
95
96 if ( verbose & VERB_PROCESS ) {
97 if ( new_nimg == 1 )
98 cout << "Extracting subimage: " << img_number << endl;
99 else
100 cout << "Extracting subimages: 0 - " << pex->images() - 1 << endl;
101 cout << "Size: " << pex->size() << endl;
102 cout << "Start: " << start << endl;
103 cout << endl;
104 }
105
106 pex->fill(p->average());
107
108 for ( n=0; n<new_nimg; n++ ) {
109 oldn = n + img_number;
110 pex->image[n] = p->image[oldn];
111 pex->image[n].origin(start);
112 for ( z=0; z<pex->sizeZ(); z++ ) {
113 oldz = (long) (z + pex->image[n].origin().z());
114 if ( oldz >= 0 && oldz < p->sizeZ() ) {
115 iz = (n*pex->sizeZ() + z)*pex->sizeY();
116 jz = (oldn*p->sizeZ() + oldz)*p->sizeY();
117 for ( y=0; y<pex->sizeY(); y++ ) {
118 oldy = (long) (y + pex->image[n].origin().y());
119 if ( oldy >= 0 && oldy < p->sizeY() ) {
120 iy = (iz + y)*pex->sizeX();
121 jy = (jz + oldy)*p->sizeX();
122 for ( x=0; x<pex->sizeX(); x++ ) {
123 oldx = (long) (x + pex->image[n].origin().x());
124 if ( oldx >= 0 && oldx < p->sizeX() ) {
125 for ( c=0, i = (iy + x)*pex->channels(), j = (jy + oldx)*pex->channels(); c<pex->channels(); c++, i++, j++ )
126 pex->set(i, (*p)[j]);
127 }
128 }
129 }
130 }
131 }
132 }
133 }
134
135 pex->statistics();
136
137 return pex;
138 }
139
140 /*
141 @brief Extracts part of a bitmap image into a new bitmap image.
142 @param *p image (not altered).
143 @param int img_number image number from which to extract, -1 indicates all images.
144 @param start three-value vector = start of extracted image.
145 @param size three-vector size of extracted image.
146 @return Bimage* extracted image.
147
148 A single image (only one sub-image) is extracted from a given sub-image
149 in an image structure, starting at a specified point and with a
150 specified size.
151 The old data is not affected.
152 Statistics for the extracted image are calculated.
153 **/
154 Bimage* img_extract_bitmap(Bimage* p, int img_number, Vector3<float> start, Vector3<int> size)
155 {
156 if ( !p->data_pointer() ) return NULL;
157
158 if ( p->data_type() != Bit ) {
159 error_show("img_extract_bitmap", __FILE__, __LINE__);
160 cerr << "Error: Cannot extract a bitmap from a non-bitmap image!" << endl;
161 return NULL;
162 }
163
164 if ( size.volume() < 1 ) {
165 error_show("img_extract_bitmap", __FILE__, __LINE__);
166 cerr << "Error: Size of subimage is less than one!" << endl;
167 return NULL;
168 }
169
170 unsigned long i, j, y, z, n, new_nimg;
171 long oldn, oldx, oldy, oldz;
172
173 if ( img_number < 0 ) {
174 new_nimg = p->images();
175 img_number = 0;
176 } else {
177 new_nimg = 1;
178 if ( img_number >= p->images() ) img_number = p->images() - 1;
179 }
180
181 Bimage* pex = p->copy_header(new_nimg);
182
183 pex->size(size);
184 pex->page_size(size);
185
186 if ( verbose & VERB_PROCESS ) {
187 cout << "Extracting a bitmap subimage:" << endl;
188 if ( new_nimg == 1 )
189 cout << "Image number: " << img_number << endl;
190 else
191 cout << "Image numbers: 0 - " << pex->images() - 1 << endl;
192 cout << "Size: " << pex->size() << endl;
193 cout << "Start: " << start << endl;
194 cout << endl;
195 } else if ( verbose & VERB_LABEL )
196 cout << "Extracting a bitmap subimage" << endl << endl;
197
198 unsigned long linesize = pex->page_size().x()/8;
199 unsigned char* data = p->data_pointer();
200 unsigned char* nudata = pex->data_alloc();
201
202 for ( n=0; n<new_nimg; n++ ) {
203 pex->image[n].origin(start);
204 oldn = n + img_number;
205 for ( z=0; z<pex->sizeZ(); z++ ) {
206 oldz = (long) (z + pex->image[n].origin().z());
207 for ( y=0; y<pex->sizeY(); y++ ) {
208 oldy = (long) (y + pex->image[n].origin().y());
209 oldx = (long) (pex->image[n].origin().x());
210 i = ((n*pex->sizeZ() + z)*pex->sizeY() + y)*linesize;
211 j = (((oldn*p->sizeZ() + oldz)*p->sizeY() + oldy)*p->sizeX() + oldx)/8;
212 memcpy(nudata+i, data+j, linesize);
213 }
214 }
215 }
216
217 pex->statistics();
218
219 return pex;
220 }
221
237 Bimage* img_extract_shell(Bimage* p, int img_number, float minrad, float maxrad)
238 {
239 if ( !p->data_pointer() ) return NULL;
240
241 unsigned long i;
242 unsigned long x, y, z, n, c, new_nimg;
243 double rx2, ry2, rz2, r2;
244
245 if ( minrad > maxrad ) swap(minrad, maxrad);
246 if ( minrad < 0 ) minrad = 0;
247 if ( maxrad > p->sizeX() ) maxrad = p->sizeX() - 1;
248
249 double minrad2 = minrad*minrad;
250 double maxrad2 = maxrad*maxrad;
251
252 if ( img_number < 0 ) {
253 new_nimg = p->images();
254 img_number = 0;
255 } else {
256 new_nimg = 1;
257 if ( img_number >= p->images() ) img_number = p->images() - 1;
258 }
259
260 Bimage* pex = p->copy_header(new_nimg);
261 pex->data_alloc();
262
263 if ( verbose & VERB_PROCESS ) {
264 if ( new_nimg == 1 )
265 cout << "Extracting subimage: " << img_number << endl;
266 else
267 cout << "Extracting subimages: 0 - " << pex->images() - 1 << endl;
268 cout << "Shell: " << minrad << " " << maxrad << endl;
269 cout << endl;
270 }
271
272 pex->fill(p->average());
273
274 for ( n=0; n<new_nimg; n++ ) {
275 for ( z=0; z<pex->sizeZ(); z++ ) {
276 if ( p->sizeZ() > 1 ) {
277 rz2 = z - pex->image[n].origin().z();
278 rz2 *= rz2;
279 } else rz2 = 0;
280 for ( y=0; y<pex->sizeY(); y++ ) {
281 ry2 = y - pex->image[n].origin().y();
282 ry2 *= ry2;
283 for ( x=0; x<pex->sizeX(); x++ ) {
284 rx2 = x - pex->image[n].origin().x();
285 rx2 *= rx2;
286 r2 = rx2 + ry2 + rz2;
287 if ( r2 >= minrad2 && r2 <= maxrad2 ) {
288 i = (((n*pex->sizeZ() + z)*pex->sizeY() + y)*pex->sizeX() + x)*pex->channels();
289 for ( c=0; c<pex->channels(); c++, i++ ) pex->set(i, (*p)[i]);
290 }
291 }
292 }
293 }
294 }
295
296 pex->statistics();
297
298 return pex;
299 }
300
301 int img_extract_tile(Bimage* p, long img_number, Vector3<int> coords, Bimage* pex, long n)
302 {
303 unsigned long i, j, x, y, z, c;
304 long oldx, oldy, oldz;
305
306 for ( z=0; z<pex->sizeZ(); z++ ) {
307 oldz = z + coords.z();
308 for ( y=0; y<pex->sizeY(); y++ ) {
309 oldy = y + coords.y();
310 for ( x=0; x<pex->sizeX(); x++ ) {
311 oldx = x + coords.x();
312 if ( p->within_boundaries(oldx, oldy, oldz) ) {
313 i = pex->index(0, x, y, z, n);
314 j = p->index(0, oldx, oldy, oldz, img_number);
315 for ( c=0; c<pex->channels(); c++, i++, j++ )
316 pex->set(i, (*p)[j]);
317 } else {
318 pex->set(i, p->image[img_number].background());
319 }
320 }
321 }
322 }
323
324 pex->image[n].origin(coords);
325
326 return 0;
327 }
328
347 Bimage* img_extract_tiles(Bimage* p, int img_number, Vector3<int> start,
348 Vector3<int> size, Vector3<int> tile_size, int exceed)
349 {
350 if ( !p->data_pointer() ) return NULL;
351
352 if ( tile_size.length() < 1 ) {
353 error_show("img_extract_tiles", __FILE__, __LINE__);
354 cerr << "Error: Size of subimage is less than one!" << endl;
355 return NULL;
356 }
357
358 if ( img_number < 0 ) img_number = 0;
359 if ( img_number >= p->images() ) img_number = p->images() - 1;
360
361 unsigned long x, y, z, new_nimg(0);
362 long n;
363
364 if ( size.length() < 2 ) {
365 size[0] = p->sizeX();
366 size[1] = p->sizeY();
367 size[2] = p->sizeZ();
368 }
369
370 if ( start.x() > p->sizeX() ) start[0] = 0;
371 if ( start.y() > p->sizeY() ) start[1] = 0;
372 if ( start.z() > p->sizeZ() ) start[2] = 0;
373
374 if ( size.x() > p->sizeX() - start.x() ) size[0] = p->sizeX() - start.x();
375 if ( size.y() > p->sizeY() - start.y() ) size[1] = p->sizeY() - start.y();
376 if ( size.z() > p->sizeZ() - start.z() ) size[2] = p->sizeZ() - start.z();
377
378 tile_size = tile_size.min(size);
379
380 if ( !exceed ) size -= tile_size - 1;
381
382 p->calculate_background();
383
384 // Count the number of tiles to be extracted
385 for ( z=0; z<size.z(); z+=tile_size.z() )
386 for ( y=0; y<size.y(); y+=tile_size.y() )
387 for ( x=0; x<size.x(); x+=tile_size.x() )
388 new_nimg++;
389
390 Bimage* pex = p->copy_header(new_nimg);
391
392 pex->size(tile_size);
393 pex->page_size(tile_size);
394
395 pex->data_alloc();
396
397 if ( verbose & VERB_PROCESS ) {
398 cout << "Extracting " << pex->images() << " tiles:" << endl;
399 cout << "Start: " << start << endl;
400 cout << "Tile size: " << pex->size() << endl;
401 cout << endl;
402 } else if ( verbose & VERB_LABEL )
403 cout << "Extracting tiles" << endl << endl;
404
405 Vector3<int>* coords = new Vector3<int>[new_nimg];
406
407 for ( n=z=0; z<size.z(); z+=pex->sizeZ() )
408 for ( y=0; y<size.y(); y+=pex->sizeY() )
409 for ( x=0; x<size.x(); x+=pex->sizeX(), n++ )
410 coords[n] = Vector3<int>(x + start.x(), y + start.y(), z + start.z());
411
412 #ifdef HAVE_GCD
413 dispatch_apply(pex->images(), dispatch_get_global_queue(0, 0), ^(size_t nn){
414 img_extract_tile(p, img_number, coords[nn], pex, nn);
415 });
416 #else
417 #pragma omp parallel for
418 for ( n=0; n<pex->images(); n++ )
419 img_extract_tile(p, img_number, coords[n], pex, n);
420 #endif
421
422 delete[] coords;
423
424 pex->statistics();
425
426 return pex;
427 }
428
445 Bimage* img_extract_tiles_at_coords(Bimage* p, int img_number,
446 int ntiles, Vector3<int>* coords, Vector3<int> tile_size)
447 {
448 if ( !p->data_pointer() ) return NULL;
449
450 if ( tile_size.length() < 1 ) {
451 error_show("img_extract_tiles_at_coords", __FILE__, __LINE__);
452 cerr << "Error: Size of subimage is less than one!" << endl;
453 return NULL;
454 }
455
456 if ( tile_size.x() > p->sizeX() ) tile_size[0] = p->sizeX();
457 if ( tile_size.y() > p->sizeY() ) tile_size[1] = p->sizeY();
458 if ( tile_size.z() > p->sizeZ() ) tile_size[2] = p->sizeZ();
459
460 if ( img_number < 0 ) img_number = 0;
461
462 Bimage* pex = p->copy_header(ntiles);
463
464 pex->size(tile_size);
465 pex->page_size(tile_size);
466
467 pex->data_alloc();
468
469 if ( verbose & VERB_PROCESS ) {
470 cout << "Extracting " << pex->images() << " tiles using coordinates:" << endl;
471 cout << "Tile size: " << pex->size() << endl;
472 cout << endl;
473 } else if ( verbose & VERB_LABEL )
474 cout << "Extracting tiles using coordinates" << endl << endl;
475
476 pex->fill(p->average());
477
478 #ifdef HAVE_GCD
479 dispatch_apply(pex->images(), dispatch_get_global_queue(0, 0), ^(size_t n){
480 img_extract_tile(p, img_number, coords[n], pex, n);
481 });
482 #else
483 #pragma omp parallel for
484 for ( long n=0; n<pex->images(); n++ )
485 img_extract_tile(p, img_number, coords[n], pex, n);
486 #endif
487
488 pex->statistics();
489
490 return pex;
491 }
492
505 Bimage* img_extract_orthogonal_slices(Bimage* p, int img_num, Vector3<int> voxel,
506 Vector3<int> size)
507 {
508 if ( !p->data_pointer() ) return NULL;
509
510 if ( voxel.x() < 0 || voxel.x() >= p->sizeX() || voxel.y() < 0 ||
511 voxel.y() >= p->sizeY() || voxel.z() < 0 || voxel.z() >= p->sizeZ() ) return NULL;
512
513 if ( size.volume() < 1 ) size = Vector3<int>(p->sizeX(), p->sizeY(), p->sizeZ());
514
515 int xf, yf;
516 unsigned long i, j, iy, x, y, z, c;
517 long xo, yo, zo;
518 unsigned long h, nh = 1;
519 if ( p->sizeZ() > 1 ) nh = 3;
520 unsigned long nx = (unsigned long) (size.x());
521 unsigned long ny = (unsigned long) (size.y());
522
523 Vector3<int> start = voxel - (size * 0.5);
524 Vector3<int> end = start + size;
525 Vector3<double> origin;
526
527 if ( verbose & VERB_PROCESS ) {
528 cout << "Extracting orthogonal views:" << endl;
529 cout << "Start: " << start << endl;
530 cout << "End: " << end << endl;
531 cout << "Fill value: " << p->image->background() << endl;
532 cout << endl;
533 } else if ( verbose & VERB_LABEL )
534 cout << "Extracting orthogonal views" << endl << endl;
535
536 Bimage* porth = new Bimage(p->data_type(), p->compound_type(), nx, ny, 1, nh);
537 porth->sampling(p->sampling());
538 porth->fill(p->image->background());
539
540 for ( h=0; h<nh; h++ ) {
541 porth->image[h].background(p->image->background());
542 if ( h%2 == 0 ) origin[0] = p->image->origin().x() - start.x();
543 else origin[0] = p->image->origin().z() - start.z();
544 if ( h < 2 ) origin[1] = p->image->origin().y() - start.y();
545 else origin[1] = p->image->origin().z() - start.z();
546 porth->image[h].origin(origin);
547 if ( h == 0 ) porth->image[h].view(0,0,1,0);
548 else if ( h == 1 ) porth->image[h].view(1,0,0,0);
549 else porth->image[h].view(0,1,0,0);
550 xo = voxel.x();
551 yo = voxel.y();
552 zo = voxel.z();
553 for ( y=0; y<ny; y++ ) {
554 yf = 1;
555 if ( h < 2 ) {
556 yo = (long) (y + start.y());
557 if ( yo < 0 ) yf = 0;
558 else if ( yo >= p->sizeY() ) yf = 0;
559 } else {
560 z = y;
561 zo = (long) (z + start.z());
562 if ( zo < 0 ) yf = 0;
563 else if ( zo >= p->sizeZ() ) yf = 0;
564 }
565 iy = (h*ny + y)*nx;
566 for ( x=0; x<nx; x++ ) {
567 xf = 1;
568 if ( h%2 == 0 ) {
569 xo = (long) (x + start.x());
570 if ( xo < 0 ) xf = 0;
571 else if ( xo >= p->sizeX() ) xf = 0;
572 } else {
573 z = x;
574 zo = (long) (z + start.z());
575 if ( zo < 0 ) xf = 0;
576 else if ( zo >= p->sizeZ() ) xf = 0;
577 }
578 i = (iy + x)*porth->channels();
579 if ( xf && yf ) {
580 j = (((img_num*p->sizeZ() + zo)*p->sizeY() + yo)*p->sizeX() + xo)*porth->channels();
581 for ( c=0; c<porth->channels(); c++, i++, j++ ) porth->set(i, (*p)[j]);
582 }
583 }
584 }
585 }
586
587 porth->statistics();
588
589 return porth;
590 }
591
592 int img_extract_show_chunk(Bimage* p, Bimage* pshow, int aflag, long i, long len)
593 {
594 if ( !p->data_pointer() ) return -1;
595
596 unsigned long n = p->show_image();
597 unsigned long z = p->show_slice();
598 double scale = p->show_scale();
599
600 if ( scale >= 1 ) aflag = 0; // No averaging for enlargements
601
602 int threshold = 0;
603 if ( fabs(p->show_maximum() - p->show_minimum()) < 1e-37 ) threshold = 1;
604
605 unsigned long ic, j, jz, x, y, c, m;
606 long xo, yo;
607 double xf, yf;
608 double iscale = 1.0/scale, shift = (scale < 1)? (iscale - 1)/2: 0;
609
610 double* value = new double[p->channels()];
611 double dispval[4];
612 double dscale = 255.0/(p->show_maximum() - p->show_minimum());
613 unsigned long datasize = pshow->sizeX()*pshow->sizeY();
614 RGB<double> rgb;
615 CMYK<double> cmyk;
616
617 // Note that the y-axis is flipped
618 x = i%pshow->sizeX();
619 y = i/pshow->sizeX();
620 jz = (n*p->sizeZ() + z)*p->sizeY();
621
622 m = i+len;
623 if ( m > datasize ) m = datasize;
624 for ( ; i<m; i++, x++ ) {
625 if ( x >= pshow->sizeX() ) {
626 x = 0;
627 y++;
628 }
629 xf = x*iscale;
630 yf = (pshow->sizeY() - y - 1)*iscale;
631 if ( xf >= 0 || xf <= p->sizeX()-1 || yf >=0 || yf <= p->sizeY()-1 ) {
632 yo = (long) (yf + shift);
633 xo = (long) (xf + shift);
634 if ( p->data_type() == Bit ) {
635 j = (jz + yo)*p->page_size().x() + xo;
636 pshow->set(i, 255 * (*p)[j]);
637 if ( dscale < 0 ) pshow->set(i, 255 - (*pshow)[i]);
638 } else {
639 j = ((jz + yo)*p->sizeX() + xo)*p->channels();
640 if ( aflag )
641 for ( c=0; c<p->channels(); c++ ) value[c] = p->average(c, xf, yf, z, n, iscale);
642 else
643 for ( c=0; c<p->channels(); c++, j++ ) value[c] = (*p)[j];
644 if ( p->compound_type() == TComplex ) {
645 dispval[0] = value[0]*value[0] + value[1]*value[1];
646 } else if ( p->compound_type() == TCMYK ) {
647 if ( p->data_type() == UCharacter ) for ( c=0; c<4; c++ ) value[c] /= 255;
648 cmyk = CMYK<double>(value);
649 rgb = RGB<double>(cmyk);
650 for ( c=0; c<3; c++ ) dispval[c] = 255*rgb[c];
651 } else {
652 for ( c=0; c<pshow->channels(); c++ ) dispval[c] = value[c];
653 }
654 if ( threshold ) {
655 for ( c=0; c<pshow->channels(); c++ ) {
656 if ( dispval[c] > p->show_minimum() ) dispval[c] = 255;
657 else dispval[c] = 0;
658 }
659 } else {
660 for ( c=0; c<pshow->channels(); c++ ) {
661 dispval[c] = floor(dscale*(dispval[c]-p->show_minimum())+0.5);
662 if ( dispval[c] > 255 ) dispval[c] = 255;
663 else if ( dispval[c] < 0 ) dispval[c] = 0;
664 }
665 }
666 for ( c=0, ic = i*pshow->channels(); c<pshow->channels(); c++, ic++ ) pshow->set(ic, dispval[c]);
667 }
668 }
669 }
670
671 delete [] value;
672
673 return 0;
674 }
675
693 Bimage* img_extract_show(Bimage* p, int aflag)
694 {
695 if ( !p->data_pointer() ) return NULL;
696
697 CompoundType ctype;
698
699 switch ( p->compound_type() ) {
700 case TSimple: ctype = TSimple; break;
701 case TComplex: ctype = TSimple; break;
702 case TVector3:
703 case TCMYK:
704 case TRGB: ctype = TRGB; break;
705 case TView:
706 case TRGBA: ctype = TRGBA; break;
707 default: ctype = p->compound_type();
708 }
709
710 Bimage* pshow = new Bimage(UCharacter, ctype,
711 (unsigned long) (p->show_scale()*p->sizeX()),
712 (unsigned long) (p->show_scale()*p->sizeY()), 1, 1);
713 pshow->sampling(p->sampling()/p->show_scale());
714
715 unsigned long datasize = pshow->sizeX()*pshow->sizeY();
716 long chunk_size = get_chunk_size(datasize);
717
718 #ifdef HAVE_GCD
719 dispatch_apply((datasize - 1)/chunk_size + 1, dispatch_get_global_queue(0, 0), ^(size_t i){
720 img_extract_show_chunk(p, pshow, aflag, i*chunk_size, chunk_size);
721 });
722 #else
723 #pragma omp parallel for
724 for ( long i=0; i<datasize; i+=chunk_size )
725 img_extract_show_chunk(p, pshow, aflag, i, chunk_size);
726 #endif
727
728 return pshow;
729 }
730
731
752 Bimage* img_extract_magnifying(Bimage* p, int img_num, Vector3<int> center,
753 Vector3<int> size, float scale)
754 {
755 if ( !p->data_pointer() ) return NULL;
756
757 if ( center.x() < 0 || center.x() >= p->sizeX() || center.y() < 0 ||
758 center.y() >= p->sizeY() || center.z() < 0 || center.z() >= p->sizeZ() ) return NULL;
759
760 int threshold = 0, xf, yf;
761 if ( fabs(p->show_maximum() - p->show_minimum()) < 1e-37 ) threshold = 1;
762
763 unsigned long i, j, iy, jz, x, y, z, c;
764 long xo, yo, zo;
765 unsigned long h, nh = 1;
766 if ( p->sizeZ() > 1 ) nh = 3;
767 unsigned long nx = (unsigned long) (scale*size.x());
768 unsigned long ny = (unsigned long) (scale*size.y());
769 double iscalex = 1.0/scale;
770 double iscaley = 1.0/scale;
771 double iscalez = 1.0/scale;
772 RGB<double> rgb;
773 CMYK<double> cmyk;
774
775 Vector3<int> start = center - (size * 0.5);
776 Vector3<int> end = start + size;
777
778 if ( verbose & VERB_DEBUG ) {
779 cout << "DEBUG img_extract_magnifying: start=" << start << endl;
780 cout << "DEBUG img_extract_magnifying: end=" << end << endl;
781 cout << "DEBUG img_extract_magnifying: size: nx=" << nx << " ny=" << ny << " c=" << p->channels() << endl;
782 }
783
784 CompoundType ctype;
785
786 switch ( p->compound_type() ) {
787 case TSimple: ctype = TSimple; break;
788 case TComplex: ctype = TSimple; break;
789 case TVector3:
790 case TCMYK:
791 case TRGB: ctype = TRGB; break;
792 case TView:
793 case TRGBA: ctype = TRGBA; break;
794 default: ctype = p->compound_type();
795 }
796
797 Bimage* pmag = new Bimage(UCharacter, ctype, nx, ny, 1, nh);
798 pmag->sampling(p->sampling()/scale);
799
800 double* value = new double[p->channels()];
801 double dispval[4];
802
803 double dscale = 255.0/(p->show_maximum() - p->show_minimum());
804
805 // Note that the y-axis is flipped
806 for ( h=0; h<nh; h++ ) {
807 xo = center.x();
808 yo = center.y();
809 zo = center.z();
810 for ( y=0; y<ny; y++ ) {
811 yf = 1;
812 if ( h < 2 ) {
813 yo = (long) (y*iscaley + start.y());
814 if ( yo < 0 ) yf = 0;
815 else if ( yo >= p->sizeY() ) yf = 0;
816 } else {
817 z = y;
818 zo = (long) (z*iscalez + start.z());
819 if ( zo < 0 ) yf = 0;
820 else if ( zo >= p->sizeZ() ) yf = 0;
821 }
822 iy = (h*ny + ny - 1 - y)*nx;
823 for ( x=0; x<nx; x++ ) {
824 xf = 1;
825 if ( h%2 == 0 ) {
826 xo = (long) (x*iscalex + start.x());
827 if ( xo < 0 ) xf = 0;
828 else if ( xo >= p->sizeX() ) xf = 0;
829 } else {
830 z = x;
831 zo = (long) (z*iscalez + start.z());
832 if ( zo < 0 ) xf = 0;
833 else if ( zo >= p->sizeZ() ) xf = 0;
834 }
835 if ( xf && yf ) {
836 i = (iy + x)*pmag->channels();
837 jz = (img_num*p->sizeZ() + zo)*p->sizeY();
838 if ( p->data_type() == Bit ) {
839 j = (jz + yo)*p->page_size().x() + xo;
840 pmag->set(i, 255 * (*p)[j]);
841 if ( dscale < 0 ) pmag->set(i, 255 - (*pmag)[i]);
842 } else {
843 j = ((jz + yo)*p->sizeX() + xo)*p->channels();
844 for ( c=0; c<p->channels(); c++, j++ ) value[c] = (*p)[j];
845 if ( p->compound_type() == TComplex ) {
846 dispval[0] = value[0]*value[0] + value[1]*value[1];
847 } else if ( p->compound_type() == TCMYK ) {
848 if ( p->data_type() == UCharacter ) for ( c=0; c<4; c++ ) value[c] /= 255;
849 cmyk = CMYK<double>(value);
850 rgb = RGB<double>(cmyk);
851 for ( c=0; c<3; c++ ) dispval[c] = 255*rgb[c];
852 } else {
853 for ( c=0; c<pmag->channels(); c++ ) dispval[c] = value[c];
854 }
855 if ( threshold ) {
856 for ( c=0; c<pmag->channels(); c++ ) {
857 if ( dispval[c] > p->show_minimum() ) dispval[c] = 255;
858 else dispval[c] = 0;
859 }
860 } else {
861 for ( c=0; c<pmag->channels(); c++ ) {
862 dispval[c] = floor(dscale*(dispval[c]-p->show_minimum())+0.5);
863 if ( dispval[c] > 255 ) dispval[c] = 255;
864 else if ( dispval[c] < 0 ) dispval[c] = 0;
865 }
866 }
867 for ( c=0; c<pmag->channels(); c++, i++ ) pmag->set(i, dispval[c]);
868 }
869 }
870 }
871 }
872 }
873
874 delete [] value;
875
876 return pmag;
877 }
878
889 Bimage* img_extract_particles(Bimage* p, float radius, float bad_radius,
890 int ncoord, int nbad, float* coords)
891 {
892 if ( !p->data_pointer() ) return NULL;
893 if ( ncoord < 1 ) return NULL;
894
895 unsigned long i, j, n, x, y, z, c;
896 long oldx, oldy, oldz, oldn;
897
898 Bimage* pmask = NULL;
899 Vector3<float> center;
900 if ( nbad && bad_radius > 1 ) {
901 pmask = new Bimage(UCharacter, p->compound_type(), p->sizeX(), p->sizeY(), p->sizeZ(), p->images());
902 for ( i=ncoord; i<ncoord+nbad; i++ ) {
903 center[0] = coords[4*i];
904 center[1] = coords[4*i+1];
905 center[2] = coords[4*i+2];
906 img_delete_within_radius(pmask, center, bad_radius, 0, 1, FILL_USER);
907 }
908 }
909
910 Vector3<int> box((int) (2.0*radius), (int) (2.0*radius), (int) (2.0*radius)); // Box size
911 if ( box.x() > p->sizeX() ) box[0] = p->sizeX();
912 if ( box.y() > p->sizeY() ) box[1] = p->sizeY();
913 if ( box.z() > p->sizeZ() ) box[2] = p->sizeZ();
914 Vector3<int> boxrad(box.x()/2, box.y()/2, box.z()/2); // Box halfsize
915
916 Bimage* part = new Bimage(p->data_type(), p->compound_type(), box.x(), box.y(), box.z(), ncoord);
917 part->sampling(p->sampling());
918 float* fom = part->FOM_initialize();
919
920 for ( n=0; n<part->images(); n++ ) {
921 oldn = (int) coords[4*n+3];
922 part->image[n].origin(boxrad); // Set the origin to the nominal center
923 for ( z=0; z<part->sizeZ(); z++ ) {
924 oldz = z - boxrad.z() + (int) coords[4*n+2];
925 for ( y=0; y<part->sizeY(); y++ ) {
926 oldy = y - boxrad.y() + (int) coords[4*n+1];
927 for ( x=0; x<part->sizeX(); x++ ) {
928 oldx = x - boxrad.x() + (int) coords[4*n];
929 if ( oldx >= 0 && oldx < p->sizeX() && oldy >= 0 && oldy < p->sizeY() && oldz >= 0 && oldz < p->sizeZ()) {
930 i = ((n*part->sizeZ() + z)*part->sizeY() + y)*part->sizeX() + x;
931 j = ((oldn*p->sizeZ() + oldz)*p->sizeY() + oldy)*p->sizeX() + oldx;
932 if ( !pmask || (pmask && (*pmask)[j] < 1) ) {
933 fom[i] = 1;
934 i *= p->channels();
935 j *= p->channels();
936 for ( c=0; c<p->channels(); c++, i++, j++ ) part->set(i, (*p)[j]);
937 }
938 }
939 }
940 }
941 }
942 }
943
944 delete pmask;
945
946 part->correct_background();
947
948 part->statistics();
949
950 return part;
951 }
952
966 Bimage* img_extract_filament(Bimage* p, int img_num, double width,
967 int axis, long nspline, Vector3<float>* spline)
968 {
969 if ( !p->data_pointer() ) return NULL;
970 if ( img_num < 0 ) return NULL;
971 if ( nspline < 1 ) return NULL;
972
973 if ( axis < 1 || axis > 3 ) { // Default axis selection
974 if ( p->sizeZ() > 1 ) axis = 3;
975 else axis = 1;
976 }
977
978 Vector3<int> size((int)width, (int)width, (int)width);
979 size[axis-1] = nspline;
980 if ( p->sizeX() < width ) size[0] = p->sizeX();
981 if ( p->sizeY() < width ) size[1] = p->sizeY();
982 if ( p->sizeZ() < width ) size[2] = p->sizeZ();
983
984 Bimage* pfil = new Bimage(Float, p->compound_type(), size.x(), size.y(), size.z(), 1);
985 pfil->sampling(p->sampling());
986 pfil->label(p->label());
987
988 unsigned long i, x, y, z, s;
989 double w, halfwidth(width/2);
990 Vector3<float> vref, v, vf;
991 Matrix3 mat(1);
992
993 vref[axis-1] = 1;
994
995 if ( verbose & VERB_DEBUG ) {
996 cout << "DEBUG img_extract_one_filament: img_num=" << img_num << " width=" << width << " nspline=" << nspline << endl;
997 cout << "DEBUG img_extract_one_filament: axis=" << axis << " size=" << size << endl;
998 }
999
1000 for ( i=z=0; z<size.z(); z++ ) {
1001 if ( axis == 3 ) s = z;
1002 else if ( pfil->sizeZ() > 1 ) vf[2] = z - halfwidth;
1003 for ( y=0; y<size.y(); y++ ) {
1004 if ( axis == 2 ) s = y;
1005 else if ( pfil->sizeY() > 1 ) vf[1] = y - halfwidth;
1006 for ( x=0; x<size.x(); x++, i++ ) {
1007 if ( axis == 1 ) s = x;
1008 else if ( pfil->sizeX() > 1 ) vf[0] = x - halfwidth;
1009 if ( s > 0 ) v = spline[s] - spline[s-1];
1010 else v = spline[1] - spline[0];
1011 v.normalize();
1012 mat = Matrix3(vref, v);
1013 // cout << mat << endl;
1014 v = mat * vf;
1015 v += spline[s];
1016 // w = p->interpolate(v.x(), v.y(), v.z(), img_num, p->image[img_num].background());
1017 w = p->interpolate(v, img_num, p->image[img_num].background());
1018 pfil->add(i, w);
1019 }
1020 }
1021 }
1022
1023 return pfil;
1024 }
Vector3::z
Type z()
Definition: Vector3.h:141
Bimage::sizeZ
void sizeZ(size_t nz)
Definition: Bimage.h:383
Bimage::copy_header
Bimage * copy_header()
Definition: Bimage.h:539
Bsub_image::view
void view(double x, double y, double z, double a)
Definition: Bimage.h:133
spline.h
Header file for spline interpolation.
Vector3::length
double length()
Definition: Vector3.h:198
Bimage::calculate_background
int calculate_background(size_t nn)
Calculates the background for one sub-image.
Definition: Bimage_background.cpp:26
utilities.h
Header file for general utilities.
VERB_DEBUG
#define VERB_DEBUG
Definition: utilities.h:104
TView
Definition: Bimage.h:71
Bsub_image::background
double background()
Definition: Bimage.h:124
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:294
img_delete_within_radius
int img_delete_within_radius(Bimage *p, Vector3< float > center, double radius, double width, double fill, int fill_type)
Fills a sphere within an image with a uniform value.
Definition: img_edit.cpp:116
Bimage::show_slice
size_t show_slice()
Definition: Bimage.h:489
img_extract_shell
Bimage * img_extract_shell(Bimage *p, int img_number, float minrad, float maxrad)
Extracts a shell from an image into a new image.
Definition: img_extract.cpp:237
Bimage::within_boundaries
bool within_boundaries(Vector3< double > loc)
Definition: Bimage.h:440
Complex.h
Class for complex numbers.
img_extract_particles
Bimage * img_extract_particles(Bimage *p, float radius, float bad_radius, int ncoord, int nbad, float *coords)
Extracts particles defined by a series of coordinates.
Definition: img_extract.cpp:889
Float
Definition: Bimage.h:57
Matrix3
Definition: Matrix3.h:17
Bit
Definition: Bimage.h:48
Vector3< float >
error_show
int error_show(const char *message, const char *file, int line)
Displays the error with file and line reference.
Definition: utilities.cpp:616
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:99
verbose
int verbose
Bimage::show_scale
double show_scale()
Definition: Bimage.h:491
TComplex
Definition: Bimage.h:69
Bimage::index
size_t index(size_t nx, size_t ny)
Definition: Bimage.h:387
Bimage::average
double average(size_t cc, double xf, double yf, double zf, size_t nn, double iscale)
Averages in the xy plane when scaling is less than 1.
Definition: Bimage.cpp:1150
Bimage::interpolate
double interpolate(size_t cc, double xx, double yy, double zz, size_t nn, double fill) const
Interpolates using a given location.
Definition: Bimage.cpp:1187
Bimage::statistics
size_t statistics()
Calculates the statistics for an image.
Definition: Bimage.cpp:2199
TCMYK
Definition: Bimage.h:74
TVector3
Definition: Bimage.h:70
Matrix3.h
3x3 Matrix manipulation functions
TSimple
Definition: Bimage.h:68
img_extract_tiles_at_coords
Bimage * img_extract_tiles_at_coords(Bimage *p, int img_number, int ntiles, Vector3< int > *coords, Vector3< int > tile_size)
Extracts a set of tiles at specified positions from an image into a new image.
Definition: img_extract.cpp:445
img_extract_magnifying
Bimage * img_extract_magnifying(Bimage *p, int img_num, Vector3< int > center, Vector3< int > size, float scale)
Extracts a region from an image to magnify.
Definition: img_extract.cpp:752
Bimage::size
Vector3< int > size()
Definition: Bimage.h:378
Bimage
General image parameter class.
Definition: Bimage.h:150
UCharacter
Definition: Bimage.h:49
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:223
CompoundType
CompoundType
Compound data type specifier.
Definition: Bimage.h:67
Bimage::channels
size_t channels()
Definition: Bimage.h:376
Bimage::sampling
void sampling(double s)
Definition: Bimage.h:462
img_extract.h
Header file for functions to extract parts of images.
RGB
Definition: Color.h:30
img_extract
Bimage * img_extract(Bimage *p, int img_number)
Extracts part of an image into a new image.
Definition: img_extract.cpp:35
Vector3::min
Type min()
Definition: Vector3.h:145
Bimage::show_maximum
double show_maximum()
Definition: Bimage.h:494
Vector3::x
Type x()
Definition: Vector3.h:139
img_extract_tile
int img_extract_tile(Bimage *p, long img_number, Vector3< int > coords, Bimage *pex, long n)
Definition: img_extract.cpp:301
FILL_USER
#define FILL_USER
Definition: utilities.h:139
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:130
Bimage::add
void add(size_t j, double v)
Definition: Bimage.h:262
Bimage::set
void set(size_t j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:916
img_edit.h
Header file for functions for editing image contents.
TRGB
Definition: Bimage.h:72
Bimage::images
size_t images()
Definition: Bimage.h:460
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:228
img_extract_bitmap
Bimage * img_extract_bitmap(Bimage *p, int img_number, Vector3< float > start, Vector3< int > size)
Definition: img_extract.cpp:154
Bimage::sizeX
void sizeX(size_t nx)
Definition: Bimage.h:381
Vector3::normalize
double normalize()
Definition: Vector3.h:208
Bimage::sizeY
void sizeY(size_t ny)
Definition: Bimage.h:382
img_extract_filament
Bimage * img_extract_filament(Bimage *p, int img_num, double width, int axis, long nspline, Vector3< float > *spline)
Extracts a filament defined by a series of coordinates.
Definition: img_extract.cpp:966
img_extract_show_chunk
int img_extract_show_chunk(Bimage *p, Bimage *pshow, int aflag, long i, long len)
Definition: img_extract.cpp:592
Color.h
Classes for color objects.
data
JSAMPIMAGE data
Definition: jpeglib.h:945
rwimg.h
Header file for 2D and 3D image I/O.
TRGBA
Definition: Bimage.h:73
img_extract_show
Bimage * img_extract_show(Bimage *p, int aflag)
Converts a slice from an image to a 2D plane for display.
Definition: img_extract.cpp:693
Bimage::show_image
size_t show_image()
Definition: Bimage.h:487
img_extract_tiles
Bimage * img_extract_tiles(Bimage *p, int img_number, Vector3< int > start, Vector3< int > size, Vector3< int > tile_size, int exceed)
Extracts a set of tiles from an image into a new image.
Definition: img_extract.cpp:347
Bimage::fill
void fill(double v)
Definition: Bimage.h:549
Bimage::page_size
Vector3< int > page_size()
Definition: Bimage.h:453
Bimage::show_minimum
double show_minimum()
Definition: Bimage.h:493
CMYK
Definition: Color.h:18
Bimage::label
void label(Bstring s)
Definition: Bimage.h:216
VERB_LABEL
#define VERB_LABEL
Definition: utilities.h:98
Bimage::data_type
DataType data_type()
Definition: Bimage.h:292
Vector3::volume
double volume()
Definition: Vector3.h:207
Vector3::y
Type y()
Definition: Vector3.h:140
get_chunk_size
long get_chunk_size(size_t datasize)
Returns the chunk size per thread.
Definition: utilities.cpp:581
Bimage::image
Bsub_image * image
Definition: Bimage.h:181
img_extract_orthogonal_slices
Bimage * img_extract_orthogonal_slices(Bimage *p, int img_num, Vector3< int > voxel, Vector3< int > size)
Extracts orthogonal views around a voxel.
Definition: img_extract.cpp:505
box
Definition: jquant2.c:258