#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 5058 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 5073 of file processor.h. 05074 { 05075 return "This will mask a 3-D volume using a 'flood filling' approach. It begins with a seed generated either as a sphere with \ 05076 specified 'radius' or with the 'nmaxseed' highest values. It then includes any mass connected to the seed with value higher than 'threshold'.\ 05077 Next, the mask is expanded by 'nshells'+'nshellsgauss'/2 voxels. Finally a gaussian low-pass filter is applied with a width of 'nshellsgauss'."; 05078 }
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 5063 of file processor.h. 05064 {
05065 return NAME;
05066 }
|
|
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 5080 of file processor.h. References EMAN::TypeDict::put(). 05081 { 05082 TypeDict d; 05083 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. "); 05084 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses."); 05085 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass."); 05086 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma"); 05087 d.put("nshells", EMObject::INT, "Number of 1-voxel shells to expand the mask by."); 05088 d.put("nshellsgauss", EMObject::INT, "Width in voxels of a Gaussian decay at the edge of the mask."); 05089 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume."); 05090 d.put("verbose", EMObject::INT, "How verbose to be (stdout)"); 05091 return d; 05092 }
|
|
Definition at line 5068 of file processor.h. 05069 { 05070 return new AutoMask3D2Processor(); 05071 }
|
|
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 6672 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(). 06673 { 06674 if (!image) { 06675 LOGWARN("NULL Image"); 06676 return; 06677 } 06678 06679 if (image->get_ndim() != 3) { 06680 throw ImageDimensionException("This processor was only ever designed to work on 3D images."); 06681 } 06682 06683 /* 06684 The mask writing functionality was removed to comply with an EMAN2 policy which dictates that file io is not allowed from within a processor 06685 To get around this just use the return_mask parameter. 06686 string mask_output = params.set_default("write_mask", ""); 06687 if ( mask_output != "") { 06688 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."); 06689 if (!EMUtil::is_valid_filename(mask_output)) throw InvalidParameterException("The mask output file name type is invalid or unrecognized"); 06690 } 06691 */ 06692 06693 int radius=0; 06694 if (params.has_key("radius")) { 06695 radius = params["radius"]; 06696 } 06697 int nmaxseed=0; 06698 if (params.has_key("nmaxseed")) { 06699 nmaxseed = params["nmaxseed"]; 06700 } 06701 06702 float threshold=0.0; 06703 if (params.has_key("sigma")) threshold=(float)(image->get_attr("mean"))+(float)(image->get_attr("sigma"))*(float)params["sigma"]; 06704 else threshold=params["threshold"]; 06705 06706 int nshells = params["nshells"]; 06707 int nshellsgauss = params["nshellsgauss"]; 06708 int verbose=params.set_default("verbose",0); 06709 06710 int nx = image->get_xsize(); 06711 int ny = image->get_ysize(); 06712 int nz = image->get_zsize(); 06713 int nxy=nx*ny; 06714 06715 EMData *amask = new EMData(); 06716 amask->set_size(nx, ny, nz); 06717 06718 float *dat = image->get_data(); 06719 float *dat2 = amask->get_data(); 06720 int i,j,k; 06721 size_t l = 0; 06722 06723 // Seeds with the highest valued pixels 06724 if (nmaxseed>0) { 06725 vector<Pixel> maxs=image->calc_n_highest_locations(nmaxseed); 06726 06727 for (vector<Pixel>::iterator i=maxs.begin(); i<maxs.end(); i++) { 06728 amask->set_value_at((*i).x,(*i).y,(*i).z,1.0); 06729 if (verbose) printf("Seed at %d,%d,%d (%1.3f)\n",(*i).x,(*i).y,(*i).z,(*i).value); 06730 } 06731 } 06732 06733 // Seeds with a sphere 06734 if (radius>0) { 06735 // start with an initial sphere 06736 for (k = -nz / 2; k < nz / 2; ++k) { 06737 for (j = -ny / 2; j < ny / 2; ++j) { 06738 for (i = -nx / 2; i < nx / 2; ++i,++l) { 06739 if (abs(k) > radius || abs(j) > radius || abs(i) > radius) continue; 06740 if ( (k * k + j * j + i * i) > (radius*radius) || dat[l] < threshold) continue; 06741 dat2[l] = 1.0f; 06742 } 06743 } 06744 } 06745 } 06746 06747 06748 // iteratively 'flood fills' the map... recursion would be better 06749 int done=0; 06750 int iter=0; 06751 while (!done) { 06752 iter++; 06753 done=1; 06754 if (verbose && iter%10==0) printf("%d iterations\n",iter); 06755 for (k=1; k<nz-1; ++k) { 06756 for (j=1; j<ny-1; ++j) { 06757 for (i=1; i<nx-1; ++i) { 06758 l=i+j*nx+k*nx*ny; 06759 if (dat2[l]) continue; 06760 if (dat[l]>threshold && (dat2[l-1]||dat2[l+1]||dat2[l+nx]||dat2[l-nx]||dat2[l-nxy]||dat2[l+nxy])) { 06761 dat2[l]=1.0; 06762 done=0; 06763 } 06764 } 06765 } 06766 } 06767 } 06768 06769 amask->update(); 06770 06771 if (verbose) printf("expanding mask\n"); 06772 amask->process_inplace("mask.addshells.gauss", Dict("val1", (int)(nshells+nshellsgauss/2),"val2",0)); 06773 if (verbose) printf("filtering mask\n"); 06774 amask->process_inplace("filter.lowpass.gauss", Dict("cutoff_abs", (float)(1.0f/(float)nshellsgauss))); 06775 amask->process_inplace("threshold.belowtozero", Dict("minval",(float)0.002)); // this makes the value exactly 0 beyond ~2.5 sigma 06776 06777 bool return_mask = params.set_default("return_mask",false); 06778 if (return_mask) { 06779 // 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. 06780 dat = image->get_data(); 06781 dat2 = amask->get_data(); 06782 memcpy(dat,dat2,image->get_size()*sizeof(float)); 06783 } else { 06784 image->mult(*amask); 06785 } 06786 06787 // EMAN2 policy is not to allow file io from with a processor 06788 //if (mask_output != "") { 06789 // amask->write_image(mask_output); 06790 //} 06791 06792 06793 delete amask; 06794 }
|
|
Definition at line 169 of file processor.cpp. |