#include <processor.h>
Inheritance diagram for EMAN::AutoMask2DProcessor:


Public Member Functions | |
| virtual void | process_inplace (EMData *image) |
| To process an image in-place. | |
| virtual string | get_name () const |
| Get the processor's name. | |
| virtual TypeDict | get_param_types () const |
| Get processor parameter information in a dictionary. | |
| virtual string | get_desc () const |
| Get the descrition of this specific processor. | |
Static Public Member Functions | |
| Processor * | NEW () |
Static Public Attributes | |
| const string | NAME = "mask.auto2d" |
| threshold | runs from ~ -2 to 2, negative numbers for dark protein and positive numbers for light protein (stain). | |
| filter | is expressed as a fraction of the fourier radius. |
Definition at line 4822 of file processor.h.
|
|
Get the descrition of this specific processor. This function must be overwritten by a subclass.
Implements EMAN::Processor. Definition at line 4851 of file processor.h. 04852 {
04853 return "2D version of mask.auto3d";
04854 }
|
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 4827 of file processor.h. 04828 {
04829 return NAME;
04830 }
|
|
|
Get processor parameter information in a dictionary. Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.
Reimplemented from EMAN::Processor. Definition at line 4837 of file processor.h. References EMAN::TypeDict::put(). 04838 {
04839 TypeDict d;
04840 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
04841 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
04842 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
04843 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
04844 d.put("nshells", EMObject::INT, "The number of dilation operations");
04845 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
04846 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
04847 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
04848 return d;
04849 }
|
|
|
Definition at line 4832 of file processor.h. 04833 {
04834 return new AutoMask2DProcessor();
04835 }
|
|
|
To process an image in-place. For those processors which can only be processed out-of-place, override this function to just print out some error message to remind user call the out-of-place version.
Implements EMAN::Processor. Definition at line 5267 of file processor.cpp. References abs, EMAN::EMData::calc_n_highest_locations(), EMAN::EMData::get_attr(), EMAN::EMData::get_data(), EMAN::EMData::get_ndim(), EMAN::EMData::get_size(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::Dict::has_key(), ImageDimensionException, LOGWARN, EMAN::EMData::mult(), nx, ny, EMAN::EMData::process_inplace(), EMAN::Dict::set_default(), EMAN::EMData::set_size(), EMAN::EMData::set_value_at(), and EMAN::EMData::update(). 05268 {
05269 if (!image) {
05270 LOGWARN("NULL Image");
05271 return;
05272 }
05273
05274 if (image->get_ndim() != 2) {
05275 throw ImageDimensionException("This processor only supports 2D images.");
05276 }
05277
05278 /*
05279 The mask writing functionality was removed to comply with an EMAN2 policy which dictates that file io is not allowed from within a processor
05280 To get around this just use the return_mask parameter.
05281 string mask_output = params.set_default("write_mask", "");
05282 if ( mask_output != "") {
05283 if (Util::is_file_exist(mask_output) ) throw InvalidParameterException("The mask output file name already exists. Please remove it if you don't need it.");
05284 if (!EMUtil::is_valid_filename(mask_output)) throw InvalidParameterException("The mask output file name type is invalid or unrecognized");
05285 }
05286 */
05287
05288 int radius=0;
05289 if (params.has_key("radius")) {
05290 radius = params["radius"];
05291 }
05292 int nmaxseed=0;
05293 if (params.has_key("nmaxseed")) {
05294 nmaxseed = params["nmaxseed"];
05295 }
05296
05297 float threshold=0.0;
05298 if (params.has_key("sigma")) threshold=(float)(image->get_attr("mean"))+(float)(image->get_attr("sigma"))*(float)params["sigma"];
05299 else threshold=params["threshold"];
05300
05301
05302 int nshells = params["nshells"];
05303 int nshellsgauss = params["nshellsgauss"];
05304 int verbose=params.set_default("verbose",0);
05305
05306 int nx = image->get_xsize();
05307 int ny = image->get_ysize();
05308
05309 EMData *amask = new EMData();
05310 amask->set_size(nx, ny);
05311
05312 float *dat = image->get_data();
05313 float *dat2 = amask->get_data();
05314 int i,j;
05315 size_t l = 0;
05316
05317 if (verbose) printf("%f\t%f\t%f\n",(float)image->get_attr("mean"),(float)image->get_attr("sigma"),threshold);
05318
05319 // Seeds with the highest valued pixels
05320 if (nmaxseed>0) {
05321 vector<Pixel> maxs=image->calc_n_highest_locations(nmaxseed);
05322
05323 for (vector<Pixel>::iterator i=maxs.begin(); i<maxs.end(); i++) {
05324 amask->set_value_at((*i).x,(*i).y,0,1.0);
05325 if (verbose) printf("Seed at %d,%d,%d (%1.3f)\n",(*i).x,(*i).y,(*i).z,(*i).value);
05326 }
05327 }
05328
05329 // Seeds with a circle
05330 if (radius>0) {
05331 // start with an initial circle
05332 l=0;
05333 for (j = -ny / 2; j < ny / 2; ++j) {
05334 for (i = -nx / 2; i < nx / 2; ++i,++l) {
05335 if ( abs(j) > radius || abs(i) > radius) continue;
05336 // if ( (j * j + i * i) > (radius*radius) || dat[l] < threshold) continue; // torn on the whole threshold issue here. Removing it prevents images from being totally masked out
05337 if ( (j * j + i * i) > (radius*radius) ) continue;
05338 dat2[l] = 1.0f;
05339 }
05340 }
05341 }
05342
05343 // iteratively 'flood fills' the map... recursion would be better
05344 int done=0;
05345 int iter=0;
05346 while (!done) {
05347 iter++;
05348 done=1;
05349 if (verbose && iter%10==0) printf("%d iterations\n",iter);
05350 for (j=1; j<ny-1; ++j) {
05351 for (i=1; i<nx-1; ++i) {
05352 l=i+j*nx;
05353 if (dat2[l]) continue;
05354 if (dat[l]>threshold && (dat2[l-1]||dat2[l+1]||dat2[l+nx]||dat2[l-nx])) {
05355 dat2[l]=1.0;
05356 done=0;
05357 }
05358 }
05359 }
05360 }
05361
05362 amask->update();
05363
05364 if (verbose) printf("extending mask\n");
05365 amask->process_inplace("mask.addshells.gauss", Dict("val1", nshells, "val2", nshellsgauss));
05366
05367 bool return_mask = params.set_default("return_mask",false);
05368 if (return_mask) {
05369 // Yes there is probably a much more efficient way of getting the mask itself, but I am only providing a stop gap at the moment.
05370 memcpy(dat,dat2,image->get_size()*sizeof(float));
05371 } else {
05372 image->mult(*amask);
05373 }
05374
05375 // EMAN2 policy is not to allow file io from with a processor
05376 //if (mask_output != "") {
05377 // amask->write_image(mask_output);
05378 //}
05379
05380
05381 delete amask;
05382 }
|
|
|
Definition at line 165 of file processor.cpp. |
1.3.9.1