#include <processor.h>
Inheritance diagram for EMAN::AutoMask3D2Processor:
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 string | get_desc () const |
Get the descrition of this specific processor. | |
virtual TypeDict | get_param_types () const |
Get processor parameter information in a dictionary. | |
Static Public Member Functions | |
Processor * | NEW () |
Static Public Attributes | |
const string | NAME = "mask.auto3d" |
radius | Pixel radius of a ball which is used to seed the flood filling operation | |
threshold | An isosurface threshold that suitably encases the mass | |
nshells | The number of dilation operations | |
nshellsgauss | number of Gaussian pixels to expand, following the dilation operations If true the result of the operation will produce the mask, not the masked volume |
Definition at line 4801 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 4816 of file processor.h. 04817 { 04818 return "Tries to mask out only interesting density using something akin to a flood file approach."; 04819 }
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 4806 of file processor.h. 04807 {
04808 return NAME;
04809 }
|
|
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 4821 of file processor.h. References EMAN::TypeDict::put(). 04822 { 04823 TypeDict d; 04824 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. "); 04825 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses."); 04826 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass."); 04827 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma"); 04828 d.put("nshells", EMObject::INT, "The number of dilation operations"); 04829 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations"); 04830 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume."); 04831 d.put("verbose", EMObject::INT, "How verbose to be (stdout)"); 04832 return d; 04833 }
|
|
Definition at line 4811 of file processor.h. 04812 { 04813 return new AutoMask3D2Processor(); 04814 }
|
|
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 6345 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::EMData::get_zsize(), 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(). 06346 { 06347 if (!image) { 06348 LOGWARN("NULL Image"); 06349 return; 06350 } 06351 06352 if (image->get_ndim() != 3) { 06353 throw ImageDimensionException("This processor was only ever designed to work on 3D images."); 06354 } 06355 06356 /* 06357 The mask writing functionality was removed to comply with an EMAN2 policy which dictates that file io is not allowed from within a processor 06358 To get around this just use the return_mask parameter. 06359 string mask_output = params.set_default("write_mask", ""); 06360 if ( mask_output != "") { 06361 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."); 06362 if (!EMUtil::is_valid_filename(mask_output)) throw InvalidParameterException("The mask output file name type is invalid or unrecognized"); 06363 } 06364 */ 06365 06366 int radius=0; 06367 if (params.has_key("radius")) { 06368 radius = params["radius"]; 06369 } 06370 int nmaxseed=0; 06371 if (params.has_key("nmaxseed")) { 06372 nmaxseed = params["nmaxseed"]; 06373 } 06374 06375 float threshold=0.0; 06376 if (params.has_key("sigma")) threshold=(float)(image->get_attr("mean"))+(float)(image->get_attr("sigma"))*(float)params["sigma"]; 06377 else threshold=params["threshold"]; 06378 06379 int nshells = params["nshells"]; 06380 int nshellsgauss = params["nshellsgauss"]; 06381 int verbose=params.set_default("verbose",0); 06382 06383 int nx = image->get_xsize(); 06384 int ny = image->get_ysize(); 06385 int nz = image->get_zsize(); 06386 int nxy=nx*ny; 06387 06388 EMData *amask = new EMData(); 06389 amask->set_size(nx, ny, nz); 06390 06391 float *dat = image->get_data(); 06392 float *dat2 = amask->get_data(); 06393 int i,j,k; 06394 size_t l = 0; 06395 06396 // Seeds with the highest valued pixels 06397 if (nmaxseed>0) { 06398 vector<Pixel> maxs=image->calc_n_highest_locations(nmaxseed); 06399 06400 for (vector<Pixel>::iterator i=maxs.begin(); i<maxs.end(); i++) { 06401 amask->set_value_at((*i).x,(*i).y,(*i).z,1.0); 06402 if (verbose) printf("Seed at %d,%d,%d (%1.3f)\n",(*i).x,(*i).y,(*i).z,(*i).value); 06403 } 06404 } 06405 06406 // Seeds with a sphere 06407 if (radius>0) { 06408 // start with an initial sphere 06409 for (k = -nz / 2; k < nz / 2; ++k) { 06410 for (j = -ny / 2; j < ny / 2; ++j) { 06411 for (i = -nx / 2; i < nx / 2; ++i,++l) { 06412 if (abs(k) > radius || abs(j) > radius || abs(i) > radius) continue; 06413 if ( (k * k + j * j + i * i) > (radius*radius) || dat[l] < threshold) continue; 06414 dat2[l] = 1.0f; 06415 } 06416 } 06417 } 06418 } 06419 06420 06421 // iteratively 'flood fills' the map... recursion would be better 06422 int done=0; 06423 int iter=0; 06424 while (!done) { 06425 iter++; 06426 done=1; 06427 if (verbose && iter%10==0) printf("%d iterations\n",iter); 06428 for (k=1; k<nz-1; ++k) { 06429 for (j=1; j<ny-1; ++j) { 06430 for (i=1; i<nx-1; ++i) { 06431 l=i+j*nx+k*nx*ny; 06432 if (dat2[l]) continue; 06433 if (dat[l]>threshold && (dat2[l-1]||dat2[l+1]||dat2[l+nx]||dat2[l-nx]||dat2[l-nxy]||dat2[l+nxy])) { 06434 dat2[l]=1.0; 06435 done=0; 06436 } 06437 } 06438 } 06439 } 06440 } 06441 06442 amask->update(); 06443 06444 if (verbose) printf("extending mask\n"); 06445 amask->process_inplace("mask.addshells.gauss", Dict("val1", nshells, "val2", nshellsgauss)); 06446 06447 bool return_mask = params.set_default("return_mask",false); 06448 if (return_mask) { 06449 // 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. 06450 memcpy(dat,dat2,image->get_size()*sizeof(float)); 06451 } else { 06452 image->mult(*amask); 06453 } 06454 06455 // EMAN2 policy is not to allow file io from with a processor 06456 //if (mask_output != "") { 06457 // amask->write_image(mask_output); 06458 //} 06459 06460 06461 delete amask; 06462 }
|
|
Definition at line 163 of file processor.cpp. |