#include <processor.h>
Inheritance diagram for EMAN::DistanceSegmentProcessor:
Public Member Functions | |
string | get_name () const |
Get the processor's name. | |
virtual EMData * | process (const EMData *const image) |
To proccess an image out-of-place. | |
void | process_inplace (EMData *image) |
To process an image in-place. | |
TypeDict | get_param_types () const |
Get processor parameter information in a dictionary. | |
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 = "segment.distance" |
For linear densities such as skeletons this should fill linear regions with uniformly separated points
Definition at line 679 of file processor.h.
string EMAN::DistanceSegmentProcessor::get_desc | ( | ) | const [inline, virtual] |
Get the descrition of this specific processor.
This function must be overwritten by a subclass.
Implements EMAN::Processor.
Definition at line 705 of file processor.h.
00706 { 00707 return "Segments a volume into pieces separated by distances in the specified range."; 00708 }
string EMAN::DistanceSegmentProcessor::get_name | ( | ) | const [inline, virtual] |
Get the processor's name.
Each processor is identified by a unique name.
Implements EMAN::Processor.
Definition at line 682 of file processor.h.
References NAME.
00683 { 00684 return NAME; 00685 }
TypeDict EMAN::DistanceSegmentProcessor::get_param_types | ( | ) | const [inline, virtual] |
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 690 of file processor.h.
References EMAN::EMObject::FLOAT, EMAN::EMObject::INT, and EMAN::TypeDict::put().
00691 { 00692 TypeDict d ; 00693 d.put("thr",EMObject::FLOAT,"Optional : Isosurface threshold value. Pixels below this will not be segment centers (default = 0.9)"); 00694 d.put("minsegsep",EMObject::FLOAT,"Required: Minimum segment separation in pixels. Segments too close will trigger a reseed"); 00695 d.put("maxsegsep",EMObject::FLOAT,"Required: Maximum segment separation in pixels. Segments too close will trigger a reseed"); 00696 d.put("verbose",EMObject::INT,"Be verbose while running"); 00697 return d; 00698 }
static Processor* EMAN::DistanceSegmentProcessor::NEW | ( | ) | [inline, static] |
Definition at line 700 of file processor.h.
00701 { 00702 return new DistanceSegmentProcessor(); 00703 }
To proccess an image out-of-place.
For those processors which can only be processed out-of-place, override this function to give the right behavior.
image | The image will be copied, actual process happen on copy of image. |
Reimplemented from EMAN::Processor.
Definition at line 777 of file processor.cpp.
References EMAN::EMData::calc_highest_locations(), EMAN::EMData::copy(), EMAN::EMData::get_value_at(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Util::hypot3(), nx, ny, EMAN::Processor::params, EMAN::EMData::set_attr(), EMAN::Dict::set_default(), EMAN::EMData::set_value_at(), x, and y.
00778 { 00779 EMData * result = image->copy(); 00780 00781 float thr = params.set_default("thr",0.9f); 00782 float minsegsep = params.set_default("minsegsep",5.0f); 00783 float maxsegsep = params.set_default("maxsegsep",5.1f); 00784 int verbose = params.set_default("verbose",0); 00785 00786 vector<Pixel> pixels=image->calc_highest_locations(thr); 00787 00788 vector<float> centers(3); // only 1 to start 00789 int nx=image->get_xsize(); 00790 int ny=image->get_ysize(); 00791 int nz=image->get_zsize(); 00792 // int nxy=nx*ny; 00793 00794 // seed the process with the highest valued point 00795 centers[0]=(float)pixels[0].x; 00796 centers[1]=(float)pixels[0].y; 00797 centers[2]=(float)pixels[0].z; 00798 pixels.erase(pixels.begin()); 00799 00800 // outer loop. We add one center per iteration 00801 // This is NOT a very efficient algorithm, it assumes points are fairly sparse 00802 while (pixels.size()>0) { 00803 // iterate over pixels until we find a new center (then stop), delete any 'bad' pixels 00804 // no iterators because we remove elements 00805 00806 for (unsigned int i=0; i<pixels.size(); i++) { 00807 00808 Pixel p=pixels[i]; 00809 // iterate over existing centers to see if this pixel should be removed ... technically we only should need to check the last center 00810 for (unsigned int j=0; j<centers.size(); j+=3) { 00811 float d=Util::hypot3(centers[j]-p.x,centers[j+1]-p.y,centers[j+2]-p.z); 00812 if (d<minsegsep) { // conflicts with existing center, erase 00813 pixels.erase(pixels.begin()+i); 00814 i--; 00815 break; 00816 } 00817 } 00818 } 00819 00820 int found=0; 00821 for (unsigned int i=0; i<pixels.size() && found==0; i++) { 00822 Pixel p=pixels[i]; 00823 00824 // iterate again to see if this may be a new valid center. Start at the end so we tend to build chains 00825 for (unsigned int j=centers.size()-3; j>0; j-=3) { 00826 float d=Util::hypot3(centers[j]-p.x,centers[j+1]-p.y,centers[j+2]-p.z); 00827 if (d<maxsegsep) { // we passed minsegsep question already, so we know we're in the 'good' range 00828 centers.push_back((float)p.x); 00829 centers.push_back((float)p.y); 00830 centers.push_back((float)p.z); 00831 pixels.erase(pixels.begin()+i); // in the centers list now, don't need it any more 00832 found=1; 00833 break; 00834 } 00835 } 00836 } 00837 00838 // If we went through the whole list and didn't find one, we need to reseed again 00839 if (!found && pixels.size()) { 00840 if (verbose) printf("New chain\n"); 00841 centers.push_back((float)pixels[0].x); 00842 centers.push_back((float)pixels[0].y); 00843 centers.push_back((float)pixels[0].z); 00844 pixels.erase(pixels.begin()); 00845 } 00846 00847 if (verbose) printf("%d points found\n",(int)(centers.size()/3)); 00848 } 00849 00850 // after we have our list of centers classify pixels 00851 for (int z=0; z<nz; z++) { 00852 for (int y=0; y<ny; y++) { 00853 for (int x=0; x<nz; x++) { 00854 if (image->get_value_at(x,y,z)<thr) { 00855 result->set_value_at(x,y,z,-1.0); //below threshold -> -1 (unclassified) 00856 continue; 00857 } 00858 int bcls=-1; // best matching class 00859 float bdist=(float)(nx+ny+nz); // distance for best class 00860 for (unsigned int c=0; c<centers.size()/3; c++) { 00861 float d=Util::hypot3(x-centers[c*3],y-centers[c*3+1],z-centers[c*3+2]); 00862 if (d<bdist) { bdist=d; bcls=c; } 00863 } 00864 result->set_value_at(x,y,z,(float)bcls); // set the pixel to the class number 00865 } 00866 } 00867 } 00868 00869 result->set_attr("segment_centers",centers); 00870 00871 return result; 00872 }
void DistanceSegmentProcessor::process_inplace | ( | EMData * | image | ) | [virtual] |
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.
image | The image to be processed. |
Implements EMAN::Processor.
Definition at line 770 of file processor.cpp.
00771 { 00772 printf("Process inplace not implemented. Please use process.\n"); 00773 return; 00774 }
const string DistanceSegmentProcessor::NAME = "segment.distance" [static] |