Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

EMAN::KmeansSegmentProcessor Class Reference

Segment a volume into ~n subvolumes using K-means classification. More...

#include <processor.h>

Inheritance diagram for EMAN::KmeansSegmentProcessor:

Inheritance graph
[legend]
Collaboration diagram for EMAN::KmeansSegmentProcessor:

Collaboration graph
[legend]
List of all members.

Public Member Functions

string get_name () const
 Get the processor's name.
virtual EMDataprocess (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

ProcessorNEW ()

Static Public Attributes

const string NAME = "segment.kmeans"

Detailed Description

Segment a volume into ~n subvolumes using K-means classification.

Author:
Steve Ludtke
Date:
2008/11/03
Parameters:
ctf[in] A Ctf object to use

Definition at line 720 of file processor.h.


Member Function Documentation

string EMAN::KmeansSegmentProcessor::get_desc  )  const [inline, virtual]
 

Get the descrition of this specific processor.

This function must be overwritten by a subclass.

Returns:
The description of this processor.

Implements EMAN::Processor.

Definition at line 750 of file processor.h.

00751                 {
00752                         return "Performs K-means segmentation on a volume. Note that this method uses random seeds, and thus will return different results each time it is run. Returned map contains number of segment for each voxel (or 0 for unsegmented voxels). Segmentation centers are stored in 'segmentcenters' attribute, consisting of a list of 3n floats in x,y,z triples.";
00753                 }

string EMAN::KmeansSegmentProcessor::get_name  )  const [inline, virtual]
 

Get the processor's name.

Each processor is identified by a unique name.

Returns:
The processor's name.

Implements EMAN::Processor.

Definition at line 723 of file processor.h.

00724                 {
00725                         return NAME;
00726                 }

TypeDict EMAN::KmeansSegmentProcessor::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.

Returns:
A dictionary containing the parameter info.

Reimplemented from EMAN::Processor.

Definition at line 731 of file processor.h.

References EMAN::TypeDict::put().

00732                 {
00733                         TypeDict d ;
00734                         d.put("nseg", EMObject::INT, "Number of segments to divide the image into. default=12" );
00735                         d.put("thr",EMObject::FLOAT,"Isosurface threshold value. Pixels below this will not be segmented");
00736                         d.put("ampweight",EMObject::INT,"If set, will weight centers by voxel amplitude. default = 1");
00737                         d.put("maxsegsize",EMObject::FLOAT,"Maximum radial distance from segment center to member voxel. Default=10000");
00738                         d.put("minsegsep",EMObject::FLOAT,"Minimum segment separation. Segments too close will trigger a reseed");
00739                         d.put("maxiter",EMObject::FLOAT,"Maximum number of iterations to run before stopping. Default=100");
00740                         d.put("maxvoxmove",EMObject::FLOAT,"Maximum number of voxels that can move before quitting. Default=25");
00741                         d.put("verbose",EMObject::INT,"Be verbose while running");
00742                         return d;
00743                 }

Processor* EMAN::KmeansSegmentProcessor::NEW  )  [inline, static]
 

Definition at line 745 of file processor.h.

00746                 {
00747                         return new KmeansSegmentProcessor();
00748                 }

EMData * KmeansSegmentProcessor::process const EMData *const   image  )  [virtual]
 

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.

Parameters:
image The image will be copied, actual process happen on copy of image.
Returns:
the image processing result, may or may not be the same size of the input image

Reimplemented from EMAN::Processor.

Definition at line 966 of file processor.cpp.

References EMAN::EMData::copy(), EMAN::Util::get_frand(), EMAN::EMData::get_value_at(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Util::hypot3(), nx, ny, EMAN::EMData::set_attr(), EMAN::Dict::set_default(), EMAN::EMData::set_value_at(), x, and y.

00967 {
00968         EMData * result = image->copy();
00969 
00970         int nseg = params.set_default("nseg",12);
00971         float thr = params.set_default("thr",-1.0e30f);
00972         int ampweight = params.set_default("ampweight",1);
00973         float maxsegsize = params.set_default("maxsegsize",10000.0f);
00974         float minsegsep = params.set_default("minsegsep",0.0f);
00975         int maxiter = params.set_default("maxiter",100);
00976         int maxvoxmove = params.set_default("maxvoxmove",25);
00977         int verbose = params.set_default("verbose",0);
00978 
00979         vector<float> centers(nseg*3);
00980         vector<float> count(nseg);
00981         int nx=image->get_xsize();
00982         int ny=image->get_ysize();
00983         int nz=image->get_zsize();
00984 //      int nxy=nx*ny;
00985 
00986         // seed
00987         for (int i=0; i<nseg*3; i+=3) {
00988                 centers[i]=  Util::get_frand(0.0f,(float)nx);
00989                 centers[i+1]=Util::get_frand(0.0f,(float)ny);
00990                 centers[i+2]=Util::get_frand(0.0f,(float)nz);
00991         }
00992 
00993         for (int iter=0; iter<maxiter; iter++) {
00994                 // **** classify
00995                 size_t pixmov=0;                // count of moved pixels
00996                 for (int z=0; z<nz; z++) {
00997                         for (int y=0; y<ny; y++) {
00998                                 for (int x=0; x<nz; x++) {
00999                                         if (image->get_value_at(x,y,z)<thr) {
01000                                                 result->set_value_at(x,y,z,-1.0);               //below threshold -> -1 (unclassified)
01001                                                 continue;
01002                                         }
01003                                         int bcls=-1;                    // best matching class
01004                                         float bdist=(float)(nx+ny+nz);  // distance for best class
01005                                         for (int c=0; c<nseg; c++) {
01006                                                 float d=Util::hypot3(x-centers[c*3],y-centers[c*3+1],z-centers[c*3+2]);
01007                                                 if (d<bdist) { bdist=d; bcls=c; }
01008                                         }
01009                                         if ((int)result->get_value_at(x,y,z)!=bcls) pixmov++;
01010                                         if (bdist>maxsegsize) result->set_value_at(x,y,z,-1);           // pixel is too far from any center
01011                                         else result->set_value_at(x,y,z,(float)bcls);           // set the pixel to the class number
01012                                 }
01013                         }
01014                 }
01015 
01016                 // **** adjust centers
01017                 for (int i=0; i<nseg*3; i++) centers[i]=0;
01018                 for (int i=0; i<nseg; i++) count[i]=0;
01019 
01020                 // weighted sums
01021                 for (int z=0; z<nz; z++) {
01022                         for (int y=0; y<ny; y++) {
01023                                 for (int x=0; x<nz; x++) {
01024                                         int cls = (int)result->get_value_at(x,y,z);
01025                                         if (cls==-1) continue;
01026                                         float w=1.0;
01027                                         if (ampweight) w=image->get_value_at(x,y,z);
01028 
01029                                         centers[cls*3]+=x*w;
01030                                         centers[cls*3+1]+=y*w;
01031                                         centers[cls*3+2]+=z*w;
01032                                         count[cls]+=w;
01033                                 }
01034                         }
01035                 }
01036 
01037                 // now each becomes center of mass, or gets randomly reseeded
01038                 int nreseed=0;
01039                 for (int c=0; c<nseg; c++) {
01040                         // reseed
01041                         if (count[c]==0) {
01042                                 nreseed++;
01043                                 do {
01044                                         centers[c*3]=  Util::get_frand(0.0f,(float)nx);
01045                                         centers[c*3+1]=Util::get_frand(0.0f,(float)ny);
01046                                         centers[c*3+2]=Util::get_frand(0.0f,(float)nz);
01047                                 } while (image->get_value_at((int)centers[c*3],(int)centers[c*3+1],(int)centers[c*3+2])<thr);           // This makes sure the new point is inside density
01048                         }
01049                         // center of mass
01050                         else {
01051                                 centers[c*3]/=count[c];
01052                                 centers[c*3+1]/=count[c];
01053                                 centers[c*3+2]/=count[c];
01054                         }
01055                 }
01056 
01057                 // with minsegsep, check separation
01058                 if (minsegsep>0) {
01059                         for (int c1=0; c1<nseg-1; c1++) {
01060                                 for (int c2=c1+1; c2<nseg; c2++) {
01061                                         if (Util::hypot3(centers[c1*3]-centers[c2*3],centers[c1*3+1]-centers[c2*3+1],centers[c1*3+2]-centers[c2*3+2])<=minsegsep) {
01062                                                 nreseed++;
01063                                                 do {
01064                                                         centers[c1*3]=  Util::get_frand(0.0f,(float)nx);
01065                                                         centers[c1*3+1]=Util::get_frand(0.0f,(float)ny);
01066                                                         centers[c1*3+2]=Util::get_frand(0.0f,(float)nz);
01067                                                 } while (image->get_value_at((int)centers[c1*3],(int)centers[c1*3+1],(int)centers[c1*3+2])<thr);
01068                                         }
01069                                 }
01070                         }
01071                 }
01072 
01073 
01074                 if (verbose) printf("Iteration %3d: %6ld voxels moved, %3d classes reseeded\n",iter,pixmov,nreseed);
01075                 if (nreseed==0 && pixmov<(size_t)maxvoxmove) break;             // termination conditions met
01076         }
01077 
01078         result->set_attr("segment_centers",centers);
01079 
01080         return result;
01081 }

void KmeansSegmentProcessor::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.

Parameters:
image The image to be processed.

Implements EMAN::Processor.

Definition at line 1083 of file processor.cpp.

01084 {
01085         printf("Process inplace not implemented. Please use process.\n");
01086         return;
01087 }


Member Data Documentation

const string KmeansSegmentProcessor::NAME = "segment.kmeans" [static]
 

Definition at line 82 of file processor.cpp.


The documentation for this class was generated from the following files:
Generated on Tue Jul 12 13:50:49 2011 for EMAN2 by  doxygen 1.3.9.1