#include <processor.h>
Inheritance diagram for EMAN::FlattenBackgroundProcessor:
Public Member Functions | |
void | process_inplace (EMData *image) |
To process an image in-place. | |
string | get_name () const |
Get the processor's name. | |
string | get_desc () const |
Get the descrition of this specific processor. | |
TypeDict | get_param_types () const |
Get processor parameter information in a dictionary. | |
Static Public Member Functions | |
static Processor * | NEW () |
Static Public Attributes | |
static const string | NAME = "filter.flattenbackground" |
map | an EMData object that defines the extent of the local neighbourhood - will be used for convolution | |
radius | exclusive of the mask parameter, this defines the radius of a circle/sphere that will be used for local mean subtraction |
Definition at line 3561 of file processor.h.
string EMAN::FlattenBackgroundProcessor::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 3576 of file processor.h.
string EMAN::FlattenBackgroundProcessor::get_name | ( | ) | const [inline, virtual] |
Get the processor's name.
Each processor is identified by a unique name.
Implements EMAN::Processor.
Definition at line 3566 of file processor.h.
References NAME.
03567 { 03568 return NAME; 03569 }
TypeDict EMAN::FlattenBackgroundProcessor::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 3581 of file processor.h.
References EMAN::EMObject::EMDATA, EMAN::EMObject::INT, and EMAN::TypeDict::put().
03582 { 03583 TypeDict d; 03584 d.put("mask", EMObject::EMDATA, "A mask the defines the local neighborhood that will be used to find the local mean. Exclusive of the radius argument"); 03585 d.put("radius", EMObject::INT, "The radius of circle/sphere that defines the local neighborhood. Exclusive of the mask argument"); 03586 return d; 03587 }
static Processor* EMAN::FlattenBackgroundProcessor::NEW | ( | ) | [inline, static] |
Definition at line 3571 of file processor.h.
03572 { 03573 return new FlattenBackgroundProcessor(); 03574 }
void FlattenBackgroundProcessor::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 2606 of file processor.cpp.
References EMAN::EMData::clip_inplace(), EMAN::EMData::convolute(), EMAN::EMData::get_edge_mean(), EMAN::EMData::get_ndim(), EMAN::EMData::get_value_at(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageDimensionException, InvalidParameterException, EMAN::EMData::mult(), EMAN::Processor::params, EMAN::EMData::process_inplace(), EMAN::Dict::set_default(), EMAN::EMData::set_size(), and EMAN::EMData::sub().
02607 { 02608 02609 EMData* mask = params.set_default("mask",(EMData*)0); 02610 int radius = params.set_default("radius",0); 02611 02612 if (radius != 0 && mask != 0) throw InvalidParameterException("Error - the mask and radius parameters are mutually exclusive."); 02613 02614 if (mask == 0 && radius == 0) throw InvalidParameterException("Error - you must specify either the mask or the radius parameter."); 02615 02616 // If the radius isn't 0, then turn the mask into the thing we want... 02617 bool deletemask = false; 02618 if (radius != 0) { 02619 mask = new EMData; 02620 int n = image->get_ndim(); 02621 if (n==1){ 02622 mask->set_size(2*radius+1); 02623 } else if (n==2) { 02624 mask->set_size(2*radius+1,2*radius+1); 02625 } 02626 else /*n==3*/ { 02627 mask->set_size(2*radius+1,2*radius+1,2*radius+1); 02628 } 02629 // assuming default behavior is to make a circle/sphere with using the radius of the mask 02630 mask->process_inplace("testimage.circlesphere"); 02631 } 02632 02633 // Double check that that mask isn't too big 02634 int mnx = mask->get_xsize(); int mny = mask->get_ysize(); int mnz = mask->get_zsize(); 02635 int nx = image->get_xsize(); int ny = image->get_ysize(); int nz = image->get_zsize(); 02636 int nxc = nx+mnx; int nyc = ny+mny; int nzc = nz+mnz; 02637 if (nz == 1) nzc = 1; // Sanity check 02638 if (ny == 1) nyc = 1; // Sanity check 02639 02640 if ( mnx > nx || mny > ny || mnz > nz) 02641 throw ImageDimensionException("Can not flatten using a mask that is larger than the image."); 02642 02643 // Get the normalization factor 02644 float normfac = 0.0; 02645 for (int i=0; i<mask->get_xsize()*mask->get_ysize()*mask->get_zsize(); ++i){ 02646 normfac += mask->get_value_at(i); 02647 } 02648 // If the sum is zero the user probably doesn't understand that determining a measure of the mean requires 02649 // strictly positive numbers. The user has specified a mask that consists entirely of zeros, or the mask 02650 // has a mean of zero. 02651 if (normfac == 0) throw InvalidParameterException("Error - the pixels in the mask sum to zero. This breaks the flattening procedure"); 02652 normfac = 1.0f/normfac; 02653 02654 // The mask can now be automatically resized to the dimensions of the image 02655 // bool undoclip = false; 02656 02657 Region r; 02658 if (ny == 1) r = Region((mnx-nxc)/2,nxc); 02659 else if (nz == 1) r = Region((mnx-nxc)/2, (mny-nyc)/2,nxc,nyc); 02660 else r = Region((mnx-nxc)/2, (mny-nyc)/2,(mnz-nzc)/2,nxc,nyc,nzc); 02661 mask->clip_inplace(r,0); 02662 // undoclip = true; 02663 // if ( mnx < nx || mny < ny || mnz < nz) { 02664 // Region r((mnx-nx)/2, (mny-ny)/2,(mnz-nz)/2,nx,ny,nz); 02665 // mask->clip_inplace(r); 02666 // undoclip = true; 02667 // } 02668 02669 Region r2; 02670 if (ny == 1) r2 = Region((nx-nxc)/2,nxc); 02671 else if (nz == 1) r2 = Region((nx-nxc)/2, (ny-nyc)/2,nxc,nyc); 02672 else r2 = Region((nx-nxc)/2, (ny-nyc)/2,(nz-nzc)/2,nxc,nyc,nzc); 02673 image->clip_inplace(r2,image->get_edge_mean()); 02674 // Finally do the convolution 02675 EMData* m = image->convolute(mask); 02676 // Normalize so that m is truly the local mean 02677 m->mult(normfac); 02678 // Before we can subtract, the mean must be phase shifted 02679 m->process_inplace("xform.phaseorigin.tocenter"); 02680 // Subtract the local mean 02681 // image->write_image("a.mrc"); 02682 // m->write_image("b.mrc"); 02683 image->sub(*m); // WE'RE DONE! 02684 delete m; 02685 02686 if (deletemask) { 02687 delete mask; 02688 } else { // I clipped it inplace, so undo this clipping so the user gets back what the put in 02689 Region r; 02690 if (ny == 1) r = Region((nxc-mnx)/2,mnx); 02691 else if (nz == 1) r = Region((nxc-mnx)/2, (nyc-mny)/2,mnx,mny); 02692 else r = Region((nxc-mnx)/2, (nyc-mny)/2,(nzc-mnz)/2,mnx,mny,mnz); 02693 mask->clip_inplace(r); 02694 } 02695 02696 Region r3; 02697 if (ny == 1) r3 = Region((nxc-nx)/2,nx); 02698 else if (nz == 1) r3 = Region((nxc-nx)/2, (nyc-ny)/2,nx,ny); 02699 else r3 = Region((nxc-nx)/2, (nyc-ny)/2,(nzc-nz)/2,nx,ny,nz); 02700 image->clip_inplace(r3); 02701 // if ( undoclip ) { 02702 // Region r((nx-mnx)/2, (ny-mny)/2, (nz-mnz)/2,mnx,mny,mnz); 02703 // mask->clip_inplace(r); 02704 // } 02705 02706 }
const string FlattenBackgroundProcessor::NAME = "filter.flattenbackground" [static] |