| Bsoft 2.0.5 Bernard's software package

bop.cpp
Go to the documentation of this file.
1
9 #include "rwimg.h"
10 #include "utilities.h"
11 #include "options.h"
12 #include "timer.h"
13
14 // Declaration of global variables
15 extern int verbose; // Level of output to the screen
16
17 // Usage assistance
18 const char* use[] = {
19 " ",
20 "Usage: bop [options] file1.img file2.img outfile.img",
21 "----------------------------------------------------",
22 "Binary operations for 2D and 3D images.",
23 "Only one operation can be done at a time.",
24 " ",
25 "Actions:",
26 "-slices Interpret multiple 2D images as z-slices of a single 3D image",
27 "-images Interpret slices of a single 3D image as 2D images",
28 "-add 1.4,3.6 Add two images, scaling and shifting the second.",
29 "-multiply -5.1,0.5 Multiply two images, scaling and shifting the second.",
30 "-divide -1.8,-2.4 Divide the first image by the second, scaling and shifting the second.",
31 "-largest 3.1,0.5 Maximum of two images, scaling and shifting the second.",
32 "-smallest 3.1,0.5 Minimum of two images, scaling and shifting the second.",
33 "-truncate -0.3,10 Truncate result to min and max.",
34 "-fit 6 Linear fit, excluding a percentage of voxels as outliers, output difference.",
35 "-coefficient Calculates correlation coefficients between two sets of images.",
36 "-correlate corr.img Correlate two images and generate a correlation image.",
37 "-Histomatch 20 Match histogram of image 2 to image 1, output modified image 2.",
38 "-blend 7 Blend from image 1 to image 2, output a new multi-image file.",
39 " ",
40 "Parameters:",
41 "-verbose 7 Verbosity of output.",
42 "-datatype u Force writing of a new data type.",
43 "-sampling 1.5,1.5,1.5 Sampling (A/pixel; a single value can be given).",
44 "-radius minr,maxr Correlate or fit only between min. and max. radius (pixel).",
45 " ",
46 "Input:",
47 "-Mask mask.tif Mask file to use for limiting comparisons to a defined region.",
48 " ",
49 NULL
50 };
51
52 int main(int argc, char* argv[])
53 {
54 // Initialize all settings
55 DataType nudatatype(Unknown_Type); // Conversion to new type
56 Vector3<double> sampling; // Units for the three axes (A/pixel)
57 int znswitch(0); // 0=not, 1=n2z, 2=z2n
58 int setadd(0);
59 int setmultiply(0);
60 int setdivide(0);
61 int setlargest(0);
62 int setsmallest(0);
63 int setlinear(0);
64 double excl_voxels(0); // Percentage voxels to excl_voxels from linear fit
65 int setcc(0);
66 int radiusflag(0);
67 int setminmax(0);
68 int sethisto(0), bins(0);
69 double scale(1);
70 double shift(0);
71 // double threshold(0);
72 // double fill(0);
73 double min(0), max(0);
74 double minr(0), maxr(0);
75 int blend_number(0);
76 Bstring corrfile;
77 Bstring maskfile; // Mask file name
78
79 int optind;
80 Boption* option = get_option_list(use, argc, argv, optind);
81 Boption* curropt;
82 for ( curropt = option; curropt; curropt = curropt->next ) {
83 if ( curropt->tag == "datatype" )
84 nudatatype = curropt->datatype();
85 if ( curropt->tag == "sampling" )
86 sampling = curropt->sampling();
87 if ( curropt->tag == "slices" )
88 znswitch = 1;
89 if ( curropt->tag == "images" )
90 znswitch = 2;
91 if ( curropt->tag == "add" ) {
92 if ( curropt->values(scale, shift) < 2 )
93 cerr << "-add: Both scale and shift must be specified!" << endl;
94 else setadd = 1;
95 }
96 if ( curropt->tag == "multiply" ) {
97 if ( curropt->values(scale, shift) < 2 )
98 cerr << "-multiply: Both scale and shift must be specified!" << endl;
99 else setmultiply = 1;
100 }
101 if ( curropt->tag == "divide" ) {
102 if ( curropt->values(scale, shift) < 2 )
103 cerr << "-divide: Both scale and shift must be specified!" << endl;
104 else setdivide = 1;
105 }
106 if ( curropt->tag == "largest" ) {
107 if ( curropt->values(scale, shift) < 2 )
108 cerr << "-largest: Both scale and shift must be specified!" << endl;
109 else setlargest = 1;
110 }
111 if ( curropt->tag == "smallest" ) {
112 if ( curropt->values(scale, shift) < 2 )
113 cerr << "-smallest: Both scale and shift must be specified!" << endl;
114 else setsmallest = 1;
115 }
116 if ( curropt->tag == "truncate" ) {
117 if ( curropt->values(min, max) < 2 )
118 cerr << "-truncate: Both min and max must be specified!" << endl;
119 else setminmax = 1;
120 }
121 if ( curropt->tag == "fit" ) {
122 if ( ( excl_voxels = curropt->value.real() ) < 0 )
123 cerr << "-fit: A percentage of voxels to exclude must be specified!" << endl;
124 else
125 setlinear = 1;
126 }
127 if ( curropt->tag == "coefficient" )
128 setcc = 1;
129 if ( curropt->tag == "radius" ) {
130 if ( curropt->values(minr, maxr) < 2 )
131 cerr << "-radius: Both radii must be specified!" << endl;
132 else radiusflag = 1;
133 }
134 if ( curropt->tag == "Histomatch" ) {
135 if ( ( bins = curropt->value.integer() ) < 1 )
136 cerr << "-Histomatch: The number of bins must be specified!" << endl;
137 else
138 sethisto = 1;
139 }
140 if ( curropt->tag == "blend" )
141 if ( ( blend_number = curropt->value.integer() ) < 1 )
142 cerr << "-blend: A number of images must be specified!" << endl;
143 if ( curropt->tag == "correlate" )
144 corrfile = curropt->filename();
145 if ( curropt->tag == "Mask" )
146 maskfile = curropt->filename();
147 }
148 option_kill(option);
149
150 double ti = timer_start();
151
152 // Read the input files
153 int dataflag = 0;
154 if ( optind < argc - 1 ) dataflag = 1;
155 Bimage* p1 = read_img(argv[optind++], dataflag, -1);
156 if ( p1 == NULL ) {
157 cerr << "Error: No first input file read!" << endl;
158 bexit(-1);
159 }
160
161 if ( znswitch == 1 )
162 if ( p1->images_to_slices() < 0 ) bexit(-1);
163
164 if ( znswitch == 2 )
165 if ( p1->slices_to_images() < 0 ) bexit(-1);
166
167 p1->change_type(Float);
168 if ( p1->standard_deviation() <= 0 ) p1->statistics();
169 if ( sampling.volume() > 0 ) p1->sampling(sampling);
170
171 Bimage* p2 = read_img(argv[optind++], dataflag, -1);
172 if ( p2 == NULL ) {
173 cerr << "Error: No second input file read!" << endl;
174 bexit(-1);
175 }
176
177 if ( znswitch == 1 )
178 if ( p2->images_to_slices() < 0 ) bexit(-1);
179
180 if ( znswitch == 2 )
181 if ( p2->slices_to_images() < 0 ) bexit(-1);
182
183 p2->change_type(Float);
184 if ( p2->standard_deviation() <= 0 ) p2->statistics();
185 if ( sampling.volume() > 0 ) p2->sampling(sampling);
186
187 if ( !p1->data_pointer() ) {
188 cerr << "Error: Data missing from image " << p1->file_name() << endl;
189 bexit(-1);
190 }
191 if ( !p2->data_pointer() ) {
192 cerr << "Error: Data missing from image " << p2->file_name() << endl;
193 bexit(-1);
194 }
195
196 Bimage* pmask = NULL;
197 if ( maskfile.length() )
198 pmask = read_img(maskfile, 1, -1);
199
200 Bimage* pnu = NULL;
201 if ( blend_number ) {
202 pnu = p1->blend(p2, blend_number);
203 delete p1;
204 p1 = pnu;
205 }
206
207 if ( fabs(scale - 1) > 1e-10 ) p2->multiply(scale);
208
209 if ( shift ) p2->add(shift);
210
211 if ( setadd ) // Add two images
212 p1->add(p2);
213
214 if ( setmultiply ) // Multiply two images
215 p1->multiply(p2);
216
217 if ( setdivide ) { // Divide the first image by the second image
218 if ( p2->images() == 1 ) p1->divide_one(p2);
219 else p1->divide(p2);
220 }
221
222 if ( setlargest ) // Largest of two images
223 p1->largest(p2);
224
225 if ( setsmallest ) // Smallest of two images
226 p1->smallest(p2);
227
228 int n;
229 double cc(0);
230 Vector3<double> origin(p1->image->origin());
231 if ( setlinear ) { // Do a linear fit
232 if ( !pmask && radiusflag ) {
233 pmask = new Bimage(UCharacter, p1->compound_type(), p1->size(), p1->images());
234 pmask->origin(origin);
235 pmask->mask_shell(origin, minr, maxr);
236 // write_img("mask.pif", pmask);
237 }
238 cc = p1->linear_fit(p2, pmask, excl_voxels);
239 if ( verbose & VERB_RESULT ) {
240 cout << "Image\tR-factor" << endl;
241 for ( n=0; n<p1->images(); n++ )
242 cout << n+1 << tab << p1->image[n].FOM() << endl;
243 cout << endl;
244 }
245 }
246
247 if ( corrfile.length() ) { // Calculate a correlation image
248 cc = p1->correlate(p2, minr, maxr, pmask, 1);
249 p2->label(get_cmd_line(argc, argv));
250 p2->change_type(nudatatype);
251 write_img(corrfile, p2, 0);
252 } else if ( setcc ) {
253 cc = p1->correlate(p2, minr, maxr, pmask, 0);
254 }
255
256 if ( sethisto ) {
257 if ( bins > 10 )
258 p1->histomatch(p2, bins);
259 else
260 cerr << "Too few bins!" << endl;
261 }
262
263 if ( setminmax )
264 p1->truncate_to_min_max(min, max);
265
266 // Write an output file if a file name is given
267 if ( argc > optind && strspn(argv[optind],"-") != 1 ) {
268 p1->label(get_cmd_line(argc, argv));
269 p1->change_type(nudatatype);
270 write_img(argv[optind], p1, 0);
271 }
272
273 delete p1;
274 delete p2;
275 delete pmask;
276
277 if ( verbose & VERB_TIME )
278 timer_report(ti);
279
280 bexit((int)(1000*cc));
281 }
282
Bimage::change_type
void change_type(char letter)
Get the data type indicated by a single letter code.
Definition: Bimage.cpp:1743
Bstring::real
double real()
Definition: Bstring.cpp:545
DataType
DataType
Base data type specifier.
Definition: utilities.h:146
Bimage::sampling
Vector3< double > sampling()
Definition: Bimage.h:505
Bimage::add
void add(long j, double v)
Definition: Bimage.h:308
Bimage::slices_to_images
int slices_to_images()
Changes the slices in a 3D image into a set of 2D images.
Definition: Bimage.cpp:2052
utilities.h
Header file for general utilities.
Boption::sampling
Vector3< double > sampling()
Definition: options.h:202
Boption::value
Bstring value
Definition: options.h:30
Boption::tag
Bstring tag
Definition: options.h:29
Bimage::compound_type
CompoundType compound_type()
Definition: Bimage.h:351
verbose
int verbose
Bstring::length
long length() const
Definition: Bstring.cpp:263
Bimage::truncate_to_min_max
int truncate_to_min_max(double minim, double maxim)
Truncates image data to a given minimum and maximum.
Definition: Bimage_rescale.cpp:331
Bimage::file_name
void file_name(string s)
Definition: Bimage.h:230
Bimage::multiply
void multiply(long j, Complex< double > cv)
Definition: Bimage.h:312
get_option_list
Boption * get_option_list(const char *use[], int argc, char *argv[], int &optind)
Parses command line arguments based on a template.
Definition: options.cpp:40
read_img
Bimage * read_img(char *filename, int readdata, int img_select)
General driver function to read multiple image formats.
Definition: rwimg.cpp:76
Bimage::correlate
double correlate(Bimage *p)
Calculates correlation coefficient between two images.
Definition: Bimage_correlate.cpp:36
get_cmd_line
string get_cmd_line(int argc, char **argv)
Returns the command line as a string.
Definition: utilities.cpp:36
Boption::filename
Bstring filename()
Definition: options.h:85
Bimage::mask_shell
long mask_shell(Vector3< double > origin, double rad_min, double rad_max)
Definition: Bimage.h:1314
timer.h
Utilities for timing functions.
Float
Definition: utilities.h:157
Bimage
General image parameter class.
Definition: Bimage.h:163
Bimage::linear_fit
double linear_fit(Bimage *p, Bimage *pmask, double max_exclude)
Linear least squares fit of two images.
Definition: Bimage_combine.cpp:476
Bimage::statistics
long statistics()
Calculates the statistics for an image.
Definition: Bimage_stats.cpp:22
Boption
A class for a command line input option.
Definition: options.h:26
Bimage::label
void label(string s)
Definition: Bimage.h:235
VERB_TIME
#define VERB_TIME
Definition: utilities.h:110
Bsub_image::FOM
double FOM()
Definition: Bimage.h:151
write_img
int write_img(const char *filename, Bimage *p, int compression)
General driver function to write multiple image formats.
Definition: rwimg.cpp:280
Bimage::size
Vector3< long > size() const
Definition: Bimage.h:373
Bsub_image::origin
void origin(double x, double y, double z)
Definition: Bimage.h:127
Bimage::standard_deviation
double standard_deviation()
Definition: Bimage.h:537
VERB_RESULT
#define VERB_RESULT
Definition: utilities.h:105
Boption::datatype
DataType datatype()
Definition: options.h:93
Bimage::data_pointer
unsigned char * data_pointer()
Definition: Bimage.h:261
Boption::next
Boption * next
Definition: options.h:28
UCharacter
Definition: utilities.h:149
Bstring
Definition: Bstring.h:29
Bimage::images_to_slices
int images_to_slices()
Changes the 2D images to slices in a 3D image.
Definition: Bimage.cpp:2093
Vector3< double >
timer_report
double timer_report(double lasttime)
Reports the time elapsed since a given time.
Definition: timer.cpp:67
Bimage::largest
void largest(Bimage *p)
Selects the largest of each pixel from two images.
Definition: Bimage.cpp:3706
Bimage::divide_one
void divide_one(Bimage *p, double scale=1, double shift=0)
Divides the first image by the first sub-image of the second.
Definition: Bimage.cpp:3632
main
int main(int argc, char *argv[])
Definition: bop.cpp:52
option_kill
int option_kill(Boption *option)
Deallocates a linked list of option structures.
Definition: options.cpp:109
Bimage::divide
void divide(Bimage *p, double scale=1, double shift=0)
Divides the first image by the second.
Definition: Bimage.cpp:3579
Bstring::integer
long integer()
Definition: Bstring.cpp:539
Bimage::histomatch
int histomatch(Bimage *p, long bins)
Fits two images by matching the histogram of the second to the first.
Definition: Bimage_combine.cpp:614
Unknown_Type
Definition: utilities.h:147
rwimg.h
Header file for 2D and 3D image I/O.
options.h
Header file for option handlers.
Bimage::images
long images()
Definition: Bimage.h:491
use
const char * use[]
Definition: bop.cpp:18
Vector3::volume
double volume()
Definition: Vector3.h:235
Boption::values
long values(T1 &v1, T2 &v2)
Definition: options.h:115
bexit
int bexit(int value)
Exit function for cleanup and debugging.
Definition: utilities.cpp:273
timer_start
double timer_start()
Starts timer and prints the time.
Definition: timer.cpp:52
tab
ostream & tab(ostream &out)
Definition: utilities.cpp:21
Bimage::image
Bsub_image * image
Definition: Bimage.h:188
Bimage::blend
Bimage * blend(Bimage *p, long number)
Blends the two images, creating a new set of sub-images.
Definition: Bimage_combine.cpp:108
Bimage::origin
void origin(double ox, double oy, double oz)
Definition: Bimage.h:563
Bimage::smallest
void smallest(Bimage *p)
Selects the smallest of each pixel from two images.
Definition: Bimage.cpp:3730