#include <processor.h>
Inheritance diagram for EMAN::NonConvexProcessor:
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 = "math.nonconvex" |
Definition at line 3694 of file processor.h.
string EMAN::NonConvexProcessor::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 3708 of file processor.h.
03709 { 03710 return "Makes a curve or plane monotonically decreasing and non-convex. Useful in generating background curves from power spectra. Anchored at edges and (in 2d) at the center. If local value > mean(surrounding values) => mean(surrounding values)."; 03711 }
string EMAN::NonConvexProcessor::get_name | ( | ) | const [inline, virtual] |
Get the processor's name.
Each processor is identified by a unique name.
Implements EMAN::Processor.
Definition at line 3699 of file processor.h.
References NAME.
03700 { 03701 return NAME; 03702 }
TypeDict EMAN::NonConvexProcessor::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 3713 of file processor.h.
03714 { 03715 TypeDict d; 03716 /* d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0"); 03717 d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0"); 03718 d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output");*/ 03719 return d; 03720 }
static Processor* EMAN::NonConvexProcessor::NEW | ( | ) | [inline, static] |
void NonConvexProcessor::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 2778 of file processor.cpp.
References EMAN::EMData::calc_radial_dist(), EMAN::EMData::copy(), EMAN::EMData::get_data(), EMAN::EMData::get_value_at(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageDimensionException, LOGWARN, EMAN::EMData::process_inplace(), EMAN::EMData::set_complex(), EMAN::EMData::set_fftpad(), EMAN::EMData::set_value_at_fast(), EMAN::EMData::update(), and x.
02778 { 02779 if (!image) { LOGWARN("NULL IMAGE"); return; } 02780 //int isinten=image->get_attr_default("is_intensity",0); 02781 02782 // 1-D 02783 if (image->get_ysize()==1) { 02784 02785 } 02786 // 2-D 02787 else if (image->get_zsize()==1) { 02788 // if (!isinten) throw ImageDimensionException("Only complex intensity images currently supported by NonConvexProcessor"); 02789 int nx2=image->get_xsize()/2; 02790 int ny2=image->get_ysize()/2; 02791 vector<float> rdist = image->calc_radial_dist(nx2*1.5,0,1,false); // radial distribution to make sure nonconvex values decrease radially 02792 // Make sure rdist is decreasing (or flat) 02793 for (int i=1; i<nx2; i++) { 02794 if (rdist[i]>rdist[i-1]) rdist[i]=rdist[i-1]; 02795 } 02796 02797 image->process_inplace("xform.fourierorigin.tocenter"); 02798 EMData* binary=image->copy(); 02799 02800 // First we eliminate convex points from the input image (set to zero) 02801 for (int x=0; x<image->get_xsize(); x+=2) { 02802 for (int y=1; y<image->get_ysize()-1; y++) { 02803 int r=(int)hypot((float)(x/2),(float)(y-ny2)); 02804 float cen=(*binary)(x,y); 02805 if (x==0 || x==nx2*2-2 || (cen>(*binary)(x+2,y) || cen>(*binary)(x-2,y) || cen>(*binary)(x,y+1) || cen >(*binary)(x,y-1) || (*binary)(x,y)>rdist[r])) { // point is considered nonconvex if lower than surrounding values and lower than mean 02806 image->set_value_at_fast(x/2+nx2,y,0.0); // we are turning image into a full real-space intensity image for now 02807 image->set_value_at_fast(nx2-x/2,ny2*2-y-1,0.0); 02808 } 02809 else { 02810 image->set_value_at_fast(x/2+nx2,y,cen); // we are turning image into a full real-space intensity image for now 02811 image->set_value_at_fast(nx2-x/2,ny2*2-y-1,cen); // It will contain non-zero values only for nonconvex points 02812 } 02813 } 02814 } 02815 image->set_value_at_fast(nx2+1,ny2,(*binary)(2,ny2)); // We keep the points near the Fourier origin as a central anchor even though it's convex 02816 image->set_value_at_fast(nx2-1,ny2,(*binary)(2,ny2)); // We keep the points near the Fourier origin as a central anchor even though it's convex 02817 image->set_value_at_fast(nx2,ny2+1,(*binary)(0,ny2+1)); // We keep the points near the Fourier origin as a central anchor even though it's convex 02818 image->set_value_at_fast(nx2,ny2-1,(*binary)(0,ny2-1)); // We keep the points near the Fourier origin as a central anchor even though it's convex 02819 for (int y=0; y<ny2*2; y++) image->set_value_at_fast(0,y,0.0f); 02820 02821 // Now make a binary version of the convex points 02822 float *idat=image->get_data(); 02823 float *bdat=binary->get_data(); 02824 int nxy=(nx2*ny2*4); 02825 for (int i=0; i<nxy; i++) { 02826 bdat[i]=idat[i]==0?0:1.0f; // binary version of the convex points in image 02827 } 02828 binary->update(); 02829 02830 // We now use a Gaussian filter on both images, to use Gaussian interpolation to fill in zero values 02831 image->set_complex(false); // so we can use a Gaussian filter on it 02832 binary->set_complex(false); 02833 02834 /* image->write_image("con.hdf",0);*/ 02835 image->set_fftpad(false); 02836 binary->set_fftpad(false); 02837 02838 // Gaussian blur of both images 02839 image->process_inplace("filter.lowpass.gauss",Dict("cutoff_abs",0.04f)); 02840 binary->process_inplace("filter.lowpass.gauss",Dict("cutoff_abs",0.04f)); 02841 02842 /* image->write_image("con.hdf",1); 02843 binary->write_image("con.hdf",2);*/ 02844 02845 for (int x=0; x<image->get_xsize(); x+=2) { 02846 for (int y=0; y<image->get_ysize(); y++) { 02847 float bv=binary->get_value_at(x/2+nx2,y); 02848 image->set_value_at_fast(x,y,image->get_value_at(x/2+nx2,y)/(bv<=0?1.0f:bv)); 02849 image->set_value_at_fast(x+1,y,0.0); 02850 } 02851 } 02852 image->set_complex(true); 02853 image->set_fftpad(true); 02854 image->process_inplace("xform.fourierorigin.tocorner"); 02855 delete binary; 02856 } 02857 else throw ImageDimensionException("3D maps not yet supported by NonConvexProcessor"); 02858 02859 }
const string NonConvexProcessor::NAME = "math.nonconvex" [static] |