1 #include "mrilib.h"
2
3 /*
4 [PT: Oct 15, 2018]
5 + added '-extent_ijk_to_file FF' option to get slice numbers of
6 auto-bboxing in a nice text file.
7
8 [PT: Oct 15, 2018]
9 + change where+how input dset check occurs, so subbrick selection is
10 possible
11
12 [PT: Oct 15, 2018]
13 + added a couple other slice info things:
14 '-extent_ijk' to put bounding box slices to screen
15 '-extent_ijk_midslice' to put midslice of bounding box to screen
16
17 */
18
help_autobox()19 void help_autobox()
20 {
21 printf(
22 "Usage: 3dAutobox [options] DATASET\n"
23 "Computes size of a box that fits around the volume.\n"
24 "Also can be used to crop the volume to that box.\n"
25 "\n"
26 "OPTIONS:\n"
27 "--------\n"
28 "-prefix PREFIX = Crop the input dataset to the size of the box, and\n"
29 " write an output dataset with PREFIX for the name.\n"
30 " * If -prefix is not used, no new volume is written out,\n"
31 " just the (x,y,z) extents of the voxels to be kept.\n"
32 "\n"
33 "-input DATASET = An alternate way to specify the input dataset.\n"
34 " The default method is to pass DATASET as\n"
35 " the last parameter on the command line.\n"
36 "\n"
37 "-noclust = Don't do any clustering to find box. Any non-zero\n"
38 " voxel will be preserved in the cropped volume.\n"
39 " The default method uses some clustering to find the\n"
40 " cropping box, and will clip off small isolated blobs.\n"
41 "\n"
42 "-extent: Write to standard out the spatial extent of the box\n"
43 "\n"
44 "-extent_ijk = Write out the 6 auto bbox ijk slice numbers to\n"
45 " screen:\n"
46 " imin imax jmin jmax kmin kmax\n"
47 " Note that resampling would affect the ijk vals (but\n"
48 " not necessarily the xyz ones).\n"
49 " Also note that this value is calculated before\n"
50 " any '-npad ...' option, so it would ignore that.\n"
51 "\n"
52 "-extent_ijk_to_file FF = Write out the 6 auto bbox ijk slice numbers to\n"
53 " a simple-formatted text file FF (single row file):\n"
54 " imin imax jmin jmax kmin kmax\n"
55 " (same notes as above apply).\n"
56 "\n"
57 "-extent_ijk_midslice = Write out the 3 ijk midslices of the autobox to\n"
58 " the screen:\n"
59 " imid jmid kmid\n"
60 " These are obtained via: (imin + imax)/2, etc.\n"
61 "\n"
62 "-extent_xyz_midslice = Write out the 3 xyz midslices of the autobox to\n"
63 " the screen:\n"
64 " xmid ymid zmid\n"
65 " These are obtained via: (xmin + xmax)/2, etc.\n"
66 " These follow the same meaning as '-extent'.\n"
67 "\n"
68 "-npad NNN = Number of extra voxels to pad on each side of box,\n"
69 " since some troublesome people (that's you, LRF) want\n"
70 " this feature for no apparent reason.\n"
71 " * With this option, it is possible to get a dataset that\n"
72 " is actually bigger than the input.\n"
73 " * You can input a negative value for NNN, which will\n"
74 " crop the dataset even more than the automatic method.\n"
75 "\n"
76 ) ;
77 PRINT_COMPILE_DATE ; return ;
78 }
79
80 /*----------------------------------------------------------------------------*/
81
main(int argc,char * argv[])82 int main( int argc , char * argv[] )
83 {
84 THD_3dim_dataset *dset, *outset=NULL;
85 int iarg=1, npad = 0, extent=0;
86 char *prefix=NULL, *iname=NULL;
87
88 char *oijkext = NULL;
89 FILE *fout_ijkext=NULL;
90 int extent_ijk=0;
91 int extent_ijk_midslice=0;
92 int imid=0, jmid=0, kmid=0;
93 int extent_xyz_midslice=0;
94 float xmid=0, ymid=0, zmid=0;
95
96
97 /*-- startup bureaucracy --*/
98
99 mainENTRY("3dAutobox main"); machdep(); AFNI_logger("3dAutobox",argc,argv);
100 PRINT_VERSION("3dAutobox") ;
101
102 /*-- read command line options --*/
103
104 iarg = 1 ;
105 while( iarg < argc && argv[iarg][0] == '-' ){
106
107 if( strcmp(argv[iarg],"-help") == 0 || strcmp(argv[iarg],"-h") == 0){
108 help_autobox();
109 exit(0) ;
110 }
111
112 if( strcmp(argv[iarg],"-prefix") == 0 ){
113 prefix = argv[++iarg] ;
114 if( !THD_filename_ok(prefix) ){
115 fprintf(stderr,"** 3dAutobox: Illegal string after -prefix!\n");
116 exit(1) ;
117 }
118 iarg++ ; continue ;
119 }
120
121 if( strcmp(argv[iarg],"-input") == 0 ){
122 iname = argv[++iarg] ;
123 // This is a bad check, because it doesn't permit subbrick
124 // selection! Will do check later.
125 /*if( !THD_filename_ok(iname) ){
126 fprintf(stderr,"** 3dAutobox: Illegal string after -input!\n");
127 exit(1) ;
128 }*/
129 iarg++ ; continue ;
130 }
131
132 if( strcmp(argv[iarg],"-noclust") == 0 ){
133 MRI_autobbox_clust(0) ; /* turn of clustering and clipping */
134 THD_autobbox_clip(0) ;
135 iarg++ ; continue ;
136 }
137
138 if( strcmp(argv[iarg],"-npad") == 0 ){
139 npad = (int)strtod(argv[++iarg],NULL) ;
140 iarg++ ; continue ;
141 }
142
143 if( strcmp(argv[iarg],"-extent_ijk") == 0 ){
144 extent_ijk = 1 ;
145 iarg++ ; continue ;
146 }
147
148 if( strcmp(argv[iarg],"-extent_ijk_to_file") == 0 ){
149 if( ++iarg >= argc )
150 ERROR_exit("Need argument after '-extent_ijk_to_file'\n") ;
151 oijkext = argv[iarg];
152 iarg++ ; continue ;
153 }
154
155 if( strcmp(argv[iarg],"-extent_ijk_midslice") == 0 ){
156 extent_ijk_midslice = 1 ;
157 iarg++ ; continue ;
158 }
159
160 if( strcmp(argv[iarg],"-extent_xyz_midslice") == 0 ){
161 extent_xyz_midslice = 1 ;
162 iarg++ ; continue ;
163 }
164
165 if( strcmp(argv[iarg],"-extent") == 0 ){
166 extent = 1 ;
167 iarg++ ; continue ;
168 }
169
170 /*- washappenin, dood? -*/
171
172 ERROR_message("** 3dAutobox: %s makes no sense here.\n",
173 argv[iarg]) ;
174 suggest_best_prog_option(argv[0], argv[iarg]);
175 exit(1);
176 }
177
178 if( argc < 2){ help_autobox(); exit(0); }
179
180 /* got input ? */
181
182 if( iarg == argc-1 )
183 iname = argv[iarg] ;
184 else if (iarg != argc)
185 ERROR_exit("** 3dAutobox: %s is nonsense on the line \n"
186 " I know you're John; stop pretending you have an accent!",
187 argv[iarg]) ;
188
189 if( !iname )
190 ERROR_exit("** 3dAutobox: Where is my input?") ;
191
192 /*-- read data --*/
193
194 dset = THD_open_dataset(iname);
195 // Check here instead of after -input.
196 if( dset == NULL )
197 ERROR_exit("Can't open time series dataset '%s'.",iname);
198 CHECK_OPEN_ERROR(dset,iname);
199
200 if( DSET_BRICK_TYPE(dset,0) != MRI_short &&
201 DSET_BRICK_TYPE(dset,0) != MRI_byte &&
202 DSET_BRICK_TYPE(dset,0) != MRI_float )
203 ERROR_exit("** ILLEGAL dataset type: %s :-(",
204 MRI_type_name[DSET_BRICK_TYPE(dset,0)]) ;
205
206 DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ;
207
208 {
209 int nx=DSET_NX(dset), ny=DSET_NY(dset), nz=DSET_NZ(dset), nxy=nx*ny ;
210 int xm=-1,xp=-1,ym=-1,yp=-1,zm=-1,zp=-1;
211 THD_autobbox( dset , &xm,&xp , &ym,&yp , &zm,&zp, NULL ) ;
212
213 xm -= npad; ym -= npad; zm -= npad; /* for LRF */
214 xp += npad; yp += npad; zp += npad;
215
216 INFO_message("Auto bbox: x=%d..%d y=%d..%d z=%d..%d\n",
217 xm,xp,ym,yp,zm,zp ) ;
218
219 // [PT: Oct 18, 2018] New output text file, if desired
220 if( oijkext ) {
221 if( (fout_ijkext = fopen(oijkext, "w")) == NULL ) {
222 fprintf(stderr, "\n\nError opening file %s.\n", oijkext);
223 exit(1);
224 }
225 fprintf( fout_ijkext, "%8d %8d %8d %8d %8d %8d\n",
226 xm, xp, ym, yp, zm, zp );
227 fclose(fout_ijkext);
228 INFO_message("Wrote ijk extents file: %s", oijkext);
229 }
230
231 if( extent_ijk )
232 printf( "%8d %8d %8d %8d %8d %8d\n",
233 xm, xp, ym, yp, zm, zp );
234
235 if( extent_ijk_midslice ) {
236 imid = (xm + xp) / 2; // integer division fine, b/c we need ints
237 jmid = (ym + yp) / 2;
238 kmid = (zm + zp) / 2;
239 printf( "%8d %8d %8d\n", imid, jmid, kmid );
240 }
241
242
243 if ( (extent && !prefix) || (extent_xyz_midslice && !prefix) )
244 prefix = "EXTENT_ONLY";
245
246 if( prefix ){
247 outset = THD_zeropad( dset ,
248 -xm, xp-nx+1,
249 -ym, yp-ny+1,
250 -zm, zp-nz+1,
251 prefix , ZPAD_IJK ) ;
252 if( THD_deathcon() && THD_is_file(DSET_HEADNAME(outset)) )
253 ERROR_exit("3dAutobox: output file %s already exists :-(",
254 DSET_HEADNAME(outset) ) ;
255
256 if( outset == NULL )
257 ERROR_exit("3dAutobox: Some error occurred in processing :-(") ;
258
259 tross_Copy_History( dset , outset ) ; /* 31 Jan 2001 - RWCox */
260 tross_Make_History( "3dAutobox" , argc,argv , outset ) ;
261
262 if (!strstr(prefix,"EXTENT_ONLY")) {
263 DSET_write(outset) ;
264 INFO_message("3dAutobox: output dataset = %s",
265 DSET_BRIKNAME(outset)) ;
266 }
267 if (extent) {
268 float RL_AP_IS[6];
269 THD_dset_extent(outset, '-', RL_AP_IS);
270 printf("Extent auto bbox: R=%f L=%f A=%f P=%f I=%f S=%f\n",
271 RL_AP_IS[0],RL_AP_IS[1],
272 RL_AP_IS[2],RL_AP_IS[3],
273 RL_AP_IS[4],RL_AP_IS[5] ) ;
274 }
275 if( extent_xyz_midslice ) {
276 INFO_message("aaa" );
277 float RL_AP_IS2[6];
278 THD_dset_extent(outset, '-', RL_AP_IS2);
279 xmid = (RL_AP_IS2[0] + RL_AP_IS2[1]) / 2.;
280 ymid = (RL_AP_IS2[2] + RL_AP_IS2[3]) / 2.;
281 zmid = (RL_AP_IS2[4] + RL_AP_IS2[5]) / 2.;
282 printf( "%10.5f %10.5f %10.5f\n", xmid, ymid, zmid );
283 }
284 }
285 }
286
287 exit(0) ;
288 }
289