#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 | |
static Processor * | NEW () |
Static Public Attributes | |
static 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 4897 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 4926 of file processor.h.
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 4902 of file processor.h. References NAME. 04903 { 04904 return NAME; 04905 }
|
|
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 4912 of file processor.h. References EMAN::EMObject::BOOL, EMAN::EMObject::FLOAT, EMAN::EMObject::INT, and EMAN::TypeDict::put(). 04913 { 04914 TypeDict d; 04915 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. "); 04916 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses."); 04917 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass."); 04918 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma"); 04919 d.put("nshells", EMObject::INT, "The number of dilation operations"); 04920 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations"); 04921 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume."); 04922 d.put("verbose", EMObject::INT, "How verbose to be (stdout)"); 04923 return d; 04924 }
|
|
Definition at line 4907 of file processor.h. 04908 { 04909 return new AutoMask2DProcessor(); 04910 }
|
|
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 5344 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(), EMAN::Processor::params, EMAN::EMData::process_inplace(), EMAN::Dict::set_default(), EMAN::EMData::set_size(), EMAN::EMData::set_value_at(), and EMAN::EMData::update(). 05345 { 05346 if (!image) { 05347 LOGWARN("NULL Image"); 05348 return; 05349 } 05350 05351 if (image->get_ndim() != 2) { 05352 throw ImageDimensionException("This processor only supports 2D images."); 05353 } 05354 05355 /* 05356 The mask writing functionality was removed to comply with an EMAN2 policy which dictates that file io is not allowed from within a processor 05357 To get around this just use the return_mask parameter. 05358 string mask_output = params.set_default("write_mask", ""); 05359 if ( mask_output != "") { 05360 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."); 05361 if (!EMUtil::is_valid_filename(mask_output)) throw InvalidParameterException("The mask output file name type is invalid or unrecognized"); 05362 } 05363 */ 05364 05365 int radius=0; 05366 if (params.has_key("radius")) { 05367 radius = params["radius"]; 05368 } 05369 int nmaxseed=0; 05370 if (params.has_key("nmaxseed")) { 05371 nmaxseed = params["nmaxseed"]; 05372 } 05373 05374 float threshold=0.0; 05375 if (params.has_key("sigma")) threshold=(float)(image->get_attr("mean"))+(float)(image->get_attr("sigma"))*(float)params["sigma"]; 05376 else threshold=params["threshold"]; 05377 05378 05379 int nshells = params["nshells"]; 05380 int nshellsgauss = params["nshellsgauss"]; 05381 int verbose=params.set_default("verbose",0); 05382 05383 int nx = image->get_xsize(); 05384 int ny = image->get_ysize(); 05385 05386 EMData *amask = new EMData(); 05387 amask->set_size(nx, ny); 05388 05389 float *dat = image->get_data(); 05390 float *dat2 = amask->get_data(); 05391 int i,j; 05392 size_t l = 0; 05393 05394 if (verbose) printf("%f\t%f\t%f\n",(float)image->get_attr("mean"),(float)image->get_attr("sigma"),threshold); 05395 05396 // Seeds with the highest valued pixels 05397 if (nmaxseed>0) { 05398 vector<Pixel> maxs=image->calc_n_highest_locations(nmaxseed); 05399 05400 for (vector<Pixel>::iterator i=maxs.begin(); i<maxs.end(); i++) { 05401 amask->set_value_at((*i).x,(*i).y,0,1.0); 05402 if (verbose) printf("Seed at %d,%d,%d (%1.3f)\n",(*i).x,(*i).y,(*i).z,(*i).value); 05403 } 05404 } 05405 05406 // Seeds with a circle 05407 if (radius>0) { 05408 // start with an initial circle 05409 l=0; 05410 for (j = -ny / 2; j < ny / 2; ++j) { 05411 for (i = -nx / 2; i < nx / 2; ++i,++l) { 05412 if ( abs(j) > radius || abs(i) > radius) continue; 05413 // 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 05414 if ( (j * j + i * i) > (radius*radius) ) continue; 05415 dat2[l] = 1.0f; 05416 } 05417 } 05418 } 05419 05420 // iteratively 'flood fills' the map... recursion would be better 05421 int done=0; 05422 int iter=0; 05423 while (!done) { 05424 iter++; 05425 done=1; 05426 if (verbose && iter%10==0) printf("%d iterations\n",iter); 05427 for (j=1; j<ny-1; ++j) { 05428 for (i=1; i<nx-1; ++i) { 05429 l=i+j*nx; 05430 if (dat2[l]) continue; 05431 if (dat[l]>threshold && (dat2[l-1]||dat2[l+1]||dat2[l+nx]||dat2[l-nx])) { 05432 dat2[l]=1.0; 05433 done=0; 05434 } 05435 } 05436 } 05437 } 05438 05439 amask->update(); 05440 05441 if (verbose) printf("extending mask\n"); 05442 amask->process_inplace("mask.addshells.gauss", Dict("val1", nshells, "val2", nshellsgauss)); 05443 05444 bool return_mask = params.set_default("return_mask",false); 05445 if (return_mask) { 05446 // 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. 05447 memcpy(dat,dat2,image->get_size()*sizeof(float)); 05448 } else { 05449 image->mult(*amask); 05450 } 05451 05452 // EMAN2 policy is not to allow file io from with a processor 05453 //if (mask_output != "") { 05454 // amask->write_image(mask_output); 05455 //} 05456 05457 05458 delete amask; 05459 }
|
|
Definition at line 4931 of file processor.h. Referenced by get_name(). |