| 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_pick.cpp
Go to the documentation of this file.
1
9 #include "Bimage.h"
10 #include "img_pick.h"
11 #include "math_util.h"
12 #include "utilities.h"
13
14 // Declaration of global variables
15 extern int verbose; // Level of output to the screen
16
17 // Internal functions
18 Bimage* img_local_cc(Bimage* p, Bimage* pt, Bimage* pm, double hires, double lores, fft_plan planf, fft_plan planb);
19
30 Bimage* img_prepare_template(Vector3<int> size, double particle_diameter)
31 {
32 double a1, a2, s1, s2, r, ds(1e30);
33 Vector3<double> center(size/2);
34
35 Bimage* p = new Bimage(Float, TSimple, size, 1);
36 p->origin(center);
37
38 s2 = particle_diameter/2;
39 s1 = s2/2;
40
41 if ( verbose & VERB_FULL ) {
42 cout << "Calculating a template image:" << endl;
43 cout << "Sigma1\tRatio\tResidual" << endl;
44 }
45
46 while ( fabs(ds) > 1e-10 ) {
47 r = s2/s1;
48 r = sqrt(exp(0.5*(r*r-1)));
49 ds = s2/r - s1;
50 if ( verbose & VERB_FULL )
51 cout << s1 << tab << r << tab << ds << endl;
52 s1 -= ds;
53 }
54
55 a2 = 1;
56 a1 = r*r*a2;
57
58 if ( verbose ) {
59 cout << "Template variables:" << endl;
60 cout << "Gaussian amplitudes: " << a1 << " " << a2 << endl;
61 cout << "Gaussian sigmas: " << s1 << " " << s2 << endl << endl;
62 }
63
64 p->gaussian_sphere(0, center, s1, -a1);
65 p->gaussian_sphere(0, center, s2, a2);
66
67 write_img("temp.map", p);
68
69 return p;
70 }
71
72 Bimage* img_prepare_template(Vector3<int> size, double particle_diameter, double gauss_edge)
73 {
74 Vector3<double> center(size/2);
75
76 Bimage* p = new Bimage(Float, TSimple, size, 1);
77 p->origin(center);
78
79 if ( verbose & VERB_PROCESS ) {
80 cout << "Calculating a template image:" << endl;
81 cout << "Particle diameter: " << particle_diameter << endl;
82 cout << "Gaussian edge: " << gauss_edge << endl << endl;
83 }
84
85 // img_add_sphere(p, center, (particle_diameter+gauss_edge)/2, gauss_edge, 1, FILL_USER);
86 // img_add_sphere(p, center, particle_diameter/2, gauss_edge, -1, FILL_USER);
87 p->sphere(center, (particle_diameter+gauss_edge)/2, gauss_edge, FILL_USER, 1);
88 p->sphere(center, particle_diameter/2, gauss_edge, FILL_USER, -1);
89
90 write_img("temp.map", p);
91
92 return p;
93 }
94
110 Bimage* img_find_template(Bimage* p, Bimage* ptemp, Bimage* pmask,
111 double hires, double lores, int bin)
112 {
113 Vector3<int> vbin(bin, bin, bin);
114 vbin = vbin.min(p->size());
115
116 Bimage* pc = p->bin_copy(vbin);
117 pc->change_type(Float);
118 pc->rescale_to_avg_std(0, 1);
119
120 ptemp->rescale_to_avg_std(0, 1);
121 Bimage* pt = ptemp->bin_copy(vbin);
122 pt->pad(pc->size(), FILL_USER, 0);
123
124 Bimage* pm = NULL;
125 if ( pmask ) pm = pmask->pad_copy(pc->size(), FILL_USER, 0);
126
127 fft_plan planf = pc->fft_setup(FFTW_FORWARD, 0);
128 fft_plan planb = pc->fft_setup(FFTW_BACKWARD, 0);
129
130 Vector3<double> shift(pt->image->origin());
131
132 if ( verbose & VERB_PROCESS ) {
133 // cout << "Number of templates: " << pt->images() << endl;
134 cout << "Template origin: " << pt->image->origin() << endl;
135 cout << "Template avg & std: " << pt->average() <<
136 tab << pt->standard_deviation() << endl;
137 }
138
139 Bimage* pcc = pc->cross_correlate(pt, hires, lores, pm, planf, planb);
140
141 delete pc;
142 delete pt;
143 delete pm;
144
145 fft_destroy_plan(planf);
146 fft_destroy_plan(planb);
147
148 pcc->shift_wrap(shift);
149
150 pcc->statistics();
151
152 return pcc;
153 }
154
169 Vector3<double>* img_find_peaks(Bimage* pcc, double excl_dist, long& ncoor)
170 {
171 unsigned long rad = (unsigned long) excl_dist/2;
172 double threshold(0);
173
174 Vector3<int> tile(pcc->size());
175 tile = tile.min(rad);
176
177 Vector3<int> start;
178 start = start.max(tile);
179 start = start.min(pcc->size()-1);
180
181 Vector3<int> end(pcc->size()-tile);
182 end = end.max(1);
183
184 Vector3<double> ori(rad, rad, rad);
185 ori = ori.min(pcc->size());
186
187 if ( verbose & VERB_PROCESS ) {
188 cout << "Finding peaks in the cross-correlation map:" << endl;
189 cout << "Exclusion distance: " << excl_dist << endl;
190 cout << "Threshold: " << threshold << endl;
191 cout << "Tile size: " << tile << endl;
192 cout << "Starting coordinates: " << start << endl;
193 cout << "Ending coordinates: " << end << endl;
194 }
195
196 unsigned long i, k, l, nc, ncp, x, y, z, xx, yy, zz, n;
197 unsigned long nt = ((pcc->sizeX()-1)/tile.x()+1)*((pcc->sizeY()-1)/tile.y()+1)*((pcc->sizeZ()-1)/tile.z()+1);
198 double max(-1e30);
199 double sigma, pix_min(4), pix_max(10);
200 Vector3<int>* ct = new Vector3<int>[nt];
201 double* cc = new double[nt];
202
203 if ( verbose & VERB_FULL )
204 cout << "Allocated number of coordinates: " << nt << endl;
205
206 for ( n=0, nc=0; n<pcc->images(); n++ ) {
207 for ( z=start.z(); z<end.z(); z+=rad ) {
208 for ( y=start.y(); y<end.y(); y+=rad ) {
209 for ( x=start.x(); x<end.x(); x+=rad ) {
210 cc[nc] = -1e30;
211 for ( zz=z; zz<z+tile.z() && zz<end.z(); zz++ ) {
212 for ( yy=y; yy<y+tile.y() && yy<end.y(); yy++ ) {
213 for ( xx=x; xx<x+tile.x() && xx<end.x(); xx++ ) {
214 i = pcc->index(0,xx,yy,zz,n);
215 if ( (*pcc)[i] > threshold && cc[nc] < (*pcc)[i] ) {
216 cc[nc] = (*pcc)[i];
217 ct[nc][0] = xx;
218 ct[nc][1] = yy;
219 ct[nc][2] = zz;
220 }
221 }
222 }
223 }
224 if ( cc[nc] > threshold ) {
225 sigma = pcc->peak_sigma(n, ct[nc], 15);
226 // cout << nc << tab << cc[nc] << tab << sigma << endl;
227 if ( sigma > pix_min && sigma < pix_max ) {
228 if ( max < cc[nc] ) max = cc[nc];
229 nc++;
230 }
231 }
232 }
233 }
234 }
235 }
236
237 threshold = kmeans_threshold(nc, cc);
238 pcc->image->FOM(threshold);
239
240 if ( verbose & VERB_PROCESS ) {
241 cout << "Number of peaks found: " << nc << endl;
242 cout << "Maximum CC: " << max << endl;
243 cout << "Threshold: " << threshold << endl;
244 }
245
246 for ( k=0, ncoor=0; k<nc; k++ ) if ( cc[k] > threshold ) {
247 for ( l=k+1; l<nc; l++ ) if ( cc[l] > threshold ) {
248 if ( (ct[k] - ct[l]).length() < excl_dist ) {
249 if ( cc[k] > cc[l] ) cc[l] = threshold - 1;
250 else cc[k] = threshold - 1;
251 }
252 }
253 if ( cc[k] > threshold ) ++ncoor;
254 }
255
256 Vector3<double>* coor = new Vector3<double>[ncoor];
257
258 for ( i=k=0; k<nc; k++ ) if ( cc[k] >= threshold )
259 coor[i++] = ct[k];
260
261 delete[] ct;
262 delete[] cc;
263
264 if ( verbose & VERB_PROCESS )
265 cout << "Number of peaks found: " << ncoor << endl << endl;
266
267 return coor;
268 }
269
270
271
272 Bimage* img_local_cc(Bimage* p, Bimage* pt, Bimage* pm, double hires, double lores, fft_plan planf, fft_plan planb)
273 {
274 if ( lores > 0 && hires > lores ) swap(hires, lores);
275
276 if ( verbose ) {
277 cout << "Local cross-correlation:" << endl;
278 cout << "Resolution limits: " << hires << " - ";
279 if ( lores > 0 ) cout << lores << " A" << endl;
280 else cout << "inf A" << endl << endl;
281 }
282
283 if ( verbose )
284 cout << "Calculating the cross-correlation map" << endl << endl;
285
286 p->change_type(Float);
287 p->rescale_to_avg_std(0, 1);
288
289 Bimage* pcc = p->cross_correlate(pt, hires, lores, NULL, planf, planb);
290
291 // write_img("pcc.map", pcc);
292
293 if ( verbose )
294 cout << "Convolving the image with the mask" << endl << endl;
295
296 Bimage* pmc = p->cross_correlate(pm, hires, lores, NULL, planf, planb);
297
298 // write_img("pmc.map", pmc);
299
300 Bimage* p2 = p->copy();
301 p2->square();
302
303 // write_img("p2.map", p2);
304
305 if ( verbose )
306 cout << "Convolving the squared image with the mask" << endl << endl;
307
308 Bimage* pmc2 = p2->cross_correlate(pm, hires, lores, NULL, planf, planb);
309
310 delete p2;
311
312 // write_img("pmc2.map", pmc2);
313
314 unsigned long i, datasize = p->sizeX()*p->sizeY()*p->sizeZ();
315 double v;
316
317 // cout << "p->avg = " << p->average() << " pm->avg = " << pm->average() << " 1/f = " << 1/f << endl;
318
319 unsigned long nn(0);
320
321 for ( i=0; i<datasize; i++ ) {
322 v = (*pmc2)[i] - (*pmc)[i] * (*pmc)[i];
323 if ( v > 0 ) {
324 v = sqrt(v);
325 pcc->set(i, (*pcc)[i]/v);
326 // pcc->set(i, v);
327 } else {
328 // cout << "i = " << i << " v = " << v << endl;
329 if ( v < 0 ) nn++;
330 p->set(i, 0);
331 }
332 }
333
334 if ( verbose ) {
335 cout << "Calculating the local cross-correlation map:" << endl;
336 cout << "Sigma below zero: " << nn << endl << endl;
337 }
338
339 // write_img("plcc.map", pcc);
340
341 delete pmc;
342 delete pmc2;
343
344 Vector3<double> shift(pt->image->origin());
345
346 pcc->shift_wrap(shift);
347
348 pcc->statistics();
349
350 return pcc;
351 }
352
353 double img_marker_set_difference_at_voxel(Bimage* p, long i, Bmarker* markin, Bmarker* markout)
354 {
355 unsigned long x, y, z, n;
356 double v, sumin(0), sumout(0);
357 Bmarker* mark = NULL;
358
359 p->coordinates(i, x, y, z);
360 Vector3<float> c(x, y, z);
361
362 for ( n=0, mark = markin; mark; mark = mark->next ) {
363 v = p->get(0, mark->loc + c, 0);
364 if ( v ) {
365 sumin += v;
366 n++;
367 }
368 }
369
370 if ( n ) sumin /= n;
371
372 for ( n=0, mark = markout; mark; mark = mark->next ) {
373 v = p->get(0, mark->loc + c, 0);
374 if ( v ) {
375 sumout += v;
376 n++;
377 }
378 }
379
380 if ( n ) sumout /= n;
381
382 return sumin - sumout;
383 }
384
396 Bimage* img_marker_set_difference(Bimage* p, Bmarker* markin, Bmarker* markout)
397 {
398 Bimage* pt = p->copy_header(p->images());
399 pt->data_type(Float);
400 pt->data_alloc();
401
402 #ifdef HAVE_GCD
403 dispatch_apply(p->data_size(), dispatch_get_global_queue(0, 0), ^(size_t i){
404 pt->set(i, img_marker_set_difference_at_voxel(p, i, markin, markout));
405 });
406 #else
407 #pragma omp parallel for
408 for ( long i=0; i<p->data_size(); i++ )
409 pt->set(i, img_marker_set_difference_at_voxel(p, i, markin, markout));
410 #endif
411
412 return pt;
413 }
414
415
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1544
Vector3::z
Type z()
Definition: Vector3.h:139
Bimage::sizeZ
void sizeZ(size_t nz)
Definition: Bimage.h:332
Bimage::square
void square()
Calculates the square of an image.
Definition: Bimage_rescale.cpp:628
Bimage::copy_header
Bimage * copy_header()
Definition: Bimage.h:537
Bimage.h
Header file for image class.
utilities.h
Header file for general utilities.
Bimage::shift_wrap
int shift_wrap(Vector3< double > vec)
Shifts an image.
Definition: Bimage_transform.cpp:557
Bimage::get
double get(size_t nn, size_t xx, size_t yy, size_t zz, size_t cc=0)
Returns the data value at the given coordinates.
Definition: Bimage.cpp:843
img_marker_set_difference
Bimage * img_marker_set_difference(Bimage *p, Bmarker *markin, Bmarker *markout)
Calculates the average difference between voxels tagged by two marker sets.
Definition: img_pick.cpp:396
Bmarker
Definition: marker.h:21
Vector3< int >
Bimage::index
size_t index(size_t nx, size_t ny) const
Definition: Bimage.h:336
VERB_PROCESS
#define VERB_PROCESS
Definition: utilities.h:100
Vector3::max
Type max()
Definition: Vector3.h:149
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:1209
img_find_template
Bimage * img_find_template(Bimage *p, Bimage *ptemp, Bimage *pmask, double hires, double lores, int bin)
Picks particles using cross-correlation with a template.
Definition: img_pick.cpp:110
Bimage::size
Vector3< size_t > size() const
Definition: Bimage.h:327
Bimage::statistics
size_t statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
kmeans_threshold
double kmeans_threshold(long n, double *v)
Finds a threshold that partitions an array into foreground and background clusters.
Definition: math_util.cpp:364
Bimage::gaussian_sphere
int gaussian_sphere(size_t nn, Vector3< double > center, double sigma, double amp)
Fills a gaussian sphere within an image with a uniform value.
Definition: Bimage_edit.cpp:439
TSimple
Definition: Bimage.h:51
Float
Definition: utilities.h:150
Bimage
General image parameter class.
Definition: Bimage.h:152
Bimage::data_alloc
unsigned char * data_alloc()
Definition: Bimage.h:226
Bimage::pad_copy
Bimage * pad_copy(size_t sz, int fill_type=0, double fill=0)
Pads an image to a new size with a given fill value.
Definition: Bimage_resize.cpp:385
Bimage::rescale_to_avg_std
int rescale_to_avg_std(double nuavg=0, double nustd=1)
Rescales the image data to a given average and standard deviation.
Definition: Bimage_rescale.cpp:100
img_local_cc
Bimage * img_local_cc(Bimage *p, Bimage *pt, Bimage *pm, double hires, double lores, fft_plan planf, fft_plan planb)
Definition: img_pick.cpp:272
Bimage::sphere
int sphere(Vector3< double > center, double radius, double width=0, int fill_type=0, double fill=0)
Fills a sphere within an image with a uniform value.
Definition: Bimage_edit.cpp:387
Bimage::coordinates
void coordinates(size_t i, size_t &nx, size_t &ny, size_t &nz)
Definition: Bimage.h:363
Bsub_image::FOM
double FOM()
Definition: Bimage.h:142
Vector3::min
Type min()
Definition: Vector3.h:143
Vector3::x
Type x()
Definition: Vector3.h:137
Bimage::cross_correlate
Bimage * cross_correlate(Bimage *p, Bimage *pmask=NULL)
Definition: Bimage.h:780
FILL_USER
#define FILL_USER
Definition: utilities.h:165
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:132
Bimage::set
void set(size_t j, double v)
Sets a single value at the given index.
Definition: Bimage.cpp:977
Bmarker::next
Bmarker * next
Definition: marker.h:22
Bimage::standard_deviation
double standard_deviation()
Definition: Bimage.h:465
write_img
int write_img(const char *filename, Bimage *p)
General driver function to write multiple image formats This is the only image writing function that ...
Definition: rwimg.cpp:255
Bimage::peak_sigma
double peak_sigma(size_t nn, Vector3< int > coor, int kernel_size)
Calculates a sigma value for a cross-correlation peak.
Definition: Bimage_correlate.cpp:1314
fftwnd_data
Definition: fftw.h:355
Bimage::images
size_t images()
Definition: Bimage.h:438
Bimage::data_size
size_t data_size()
Definition: Bimage.h:225
Bimage::copy
Bimage * copy()
Copies the header information and data of an image into a new image structure.
Definition: Bimage.cpp:2414
Bimage::sizeX
void sizeX(size_t nx)
Definition: Bimage.h:330
Bimage::fft_setup
fft_plan fft_setup(fft_direction dir, int opt=0)
Sets up a plan for fast Fourier transforms.
Definition: Bimage_fft.cpp:29
verbose
int verbose
FFTW_BACKWARD
Definition: fftw.h:64
fft_destroy_plan
int fft_destroy_plan(fft_plan plan)
Deallocates a plan for fast Fourier transforms.
Definition: fft.cpp:97
Bimage::pad
int pad(size_t sz, int fill_type=0, double fill=0)
Pads an image to a new size with a given fill value.
Definition: Bimage_resize.cpp:344
Bimage::sizeY
void sizeY(size_t ny)
Definition: Bimage.h:331
Bimage::bin_copy
Bimage * bin_copy(Vector3< int > bin)
Bins by an integer size and returns a new image.
Definition: Bimage_bin.cpp:301
Bmarker::loc
Vector3< float > loc
Definition: marker.h:25
img_find_peaks
Vector3< double > * img_find_peaks(Bimage *pcc, double excl_dist, long &ncoor)
Finds the peaks in a cross-correlation map corresponding to particles.
Definition: img_pick.cpp:169
img_pick.h
Header file for functions to pick particles in images.
img_prepare_template
Bimage * img_prepare_template(Vector3< int > size, double particle_diameter)
Prepares a template for particle picking.
Definition: img_pick.cpp:30
FFTW_FORWARD
Definition: fftw.h:64
VERB_FULL
#define VERB_FULL
Definition: utilities.h:102
img_marker_set_difference_at_voxel
double img_marker_set_difference_at_voxel(Bimage *p, long i, Bmarker *markin, Bmarker *markout)
Definition: img_pick.cpp:353
Bimage::data_type
DataType data_type()
Definition: Bimage.h:305
Vector3::y
Type y()
Definition: Vector3.h:138
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::image
Bsub_image * image
Definition: Bimage.h:183
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:483
math_util.h
Header file for general utilities.