#include <processor.h>
Inheritance diagram for EMAN::MedianShrinkProcessor:
Public Member Functions | |
virtual EMData * | process (const EMData *const image) |
The medianshrink processor has its own process function to minise memory usage - if this function was not over written the base Processor class would create copy of the input image and hand it to the process_inplace function. | |
virtual void | process_inplace (EMData *image) |
Median shrink the image. | |
string | get_desc () const |
Get the descrition of this specific processor. | |
virtual string | get_name () const |
Get the processor's name. | |
virtual 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.medianshrink" |
Private Member Functions | |
void | accrue_median (EMData *to, const EMData *const from, const int shrink_factor) |
Accrue the local median in the image 'from' to the image 'to' using the given shrinkfactor An internal function that encapsulates a routine common to both process and process inplace. |
n | The shrink factor |
Definition at line 3478 of file processor.h.
void MedianShrinkProcessor::accrue_median | ( | EMData * | to, | |
const EMData *const | from, | |||
const int | shrink_factor | |||
) | [private] |
Accrue the local median in the image 'from' to the image 'to' using the given shrinkfactor An internal function that encapsulates a routine common to both process and process inplace.
to | the smaller image that will store the calculated median values | |
from | the larger image that will be used to calculate the median values | |
shrink_factor | the shrink amount |
Definition at line 2004 of file processor.cpp.
References EMAN::EMData::get_const_data(), EMAN::EMData::get_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), rdata, and EMAN::EMData::scale_pixel().
Referenced by process(), and process_inplace().
02005 { 02006 02007 int nx_old = from->get_xsize(); 02008 int ny_old = from->get_ysize(); 02009 02010 int threed_shrink_factor = shrink_factor * shrink_factor; 02011 int z_shrink_factor = 1; 02012 if (from->get_zsize() > 1) { 02013 threed_shrink_factor *= shrink_factor; 02014 z_shrink_factor = shrink_factor; 02015 } 02016 02017 float *mbuf = new float[threed_shrink_factor]; 02018 02019 02020 int nxy_old = nx_old * ny_old; 02021 02022 int nx = to->get_xsize(); 02023 int ny = to->get_ysize(); 02024 int nz = to->get_zsize(); 02025 int nxy_new = nx * ny; 02026 02027 float * rdata = to->get_data(); 02028 const float *const data_copy = from->get_const_data(); 02029 02030 for (int l = 0; l < nz; l++) { 02031 int l_min = l * shrink_factor; 02032 int l_max = l * shrink_factor + z_shrink_factor; 02033 size_t cur_l = (size_t)l * nxy_new; 02034 02035 for (int j = 0; j < ny; j++) { 02036 int j_min = j * shrink_factor; 02037 int j_max = (j + 1) * shrink_factor; 02038 size_t cur_j = j * nx + cur_l; 02039 02040 for (int i = 0; i < nx; i++) { 02041 int i_min = i * shrink_factor; 02042 int i_max = (i + 1) * shrink_factor; 02043 02044 size_t k = 0; 02045 for (int l2 = l_min; l2 < l_max; l2++) { 02046 size_t cur_l2 = l2 * nxy_old; 02047 02048 for (int j2 = j_min; j2 < j_max; j2++) { 02049 size_t cur_j2 = j2 * nx_old + cur_l2; 02050 02051 for (int i2 = i_min; i2 < i_max; i2++) { 02052 mbuf[k] = data_copy[i2 + cur_j2]; 02053 ++k; 02054 } 02055 } 02056 } 02057 02058 for (k = 0; k < size_t(threed_shrink_factor / 2 + 1); k++) { 02059 for (int i2 = k + 1; i2 < threed_shrink_factor; i2++) { 02060 if (mbuf[i2] < mbuf[k]) { 02061 float f = mbuf[i2]; 02062 mbuf[i2] = mbuf[k]; 02063 mbuf[k] = f; 02064 } 02065 } 02066 } 02067 02068 rdata[i + cur_j] = mbuf[threed_shrink_factor / 2]; 02069 } 02070 } 02071 } 02072 02073 if( mbuf ) 02074 { 02075 delete[]mbuf; 02076 mbuf = 0; 02077 } 02078 02079 to->scale_pixel((float)shrink_factor); 02080 }
string EMAN::MedianShrinkProcessor::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 3501 of file processor.h.
03502 { 03503 return "Shrink an image by a given amount , using the median value found in the pixel neighborhood."; 03504 }
virtual string EMAN::MedianShrinkProcessor::get_name | ( | ) | const [inline, virtual] |
Get the processor's name.
Each processor is identified by a unique name.
Implements EMAN::Processor.
Definition at line 3506 of file processor.h.
References NAME.
03507 { 03508 return NAME; 03509 }
virtual TypeDict EMAN::MedianShrinkProcessor::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 3515 of file processor.h.
References EMAN::EMObject::INT, and EMAN::TypeDict::put().
03516 { 03517 TypeDict d; 03518 d.put("n", EMObject::INT, "The shrink factor"); 03519 return d; 03520 }
static Processor* EMAN::MedianShrinkProcessor::NEW | ( | ) | [inline, static] |
Definition at line 3510 of file processor.h.
03511 { 03512 return new MedianShrinkProcessor(); 03513 }
The medianshrink processor has its own process function to minise memory usage - if this function was not over written the base Processor class would create copy of the input image and hand it to the process_inplace function.
This latter approach mallocs and copies more memory than necessary
image | the image that will be used to generate a 'median shrunken' image |
ImageFormatException | if the image is complex | |
InvalidValueException | if the shrink amount is not a non zero, positive integer | |
InvalidValueException | if any of the image dimensions are not divisible by the the shrink amount |
Reimplemented from EMAN::Processor.
Definition at line 1971 of file processor.cpp.
References accrue_median(), EMAN::EMData::copy_head(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageFormatException, InvalidValueException, EMAN::EMData::is_complex(), EMAN::Processor::params, EMAN::Dict::set_default(), EMAN::EMData::set_size(), and EMAN::EMData::update().
01972 { 01973 if (image->is_complex()) throw ImageFormatException("Error, the median shrink processor does not work on complex images"); 01974 01975 int shrink_factor = params.set_default("n",0); 01976 if (shrink_factor <= 1) { 01977 throw InvalidValueException(shrink_factor, 01978 "median shrink: shrink factor must > 1"); 01979 } 01980 int nx = image->get_xsize(); 01981 int ny = image->get_ysize(); 01982 int nz = image->get_zsize(); 01983 01984 01985 // if ((nx % shrink_factor != 0) || (ny % shrink_factor != 0) || (nz > 1 && (nz % shrink_factor != 0))) { 01986 // throw InvalidValueException(shrink_factor, "Image size not divisible by shrink factor"); 01987 // } 01988 01989 01990 int shrunken_nx = nx / shrink_factor; 01991 int shrunken_ny = ny / shrink_factor; 01992 int shrunken_nz = 1; 01993 if (nz > 1) shrunken_nz = nz / shrink_factor; 01994 01995 // EMData* ret = new EMData(shrunken_nx, shrunken_ny, shrunken_nz); 01996 EMData *ret = image->copy_head(); 01997 ret->set_size(shrunken_nx, shrunken_ny, shrunken_nz); 01998 01999 accrue_median(ret,image,shrink_factor); 02000 ret->update(); 02001 return ret; 02002 }
void MedianShrinkProcessor::process_inplace | ( | EMData * | image | ) | [virtual] |
Median shrink the image.
image | the image the image that will be 'median shrunken' inplace |
ImageFormatException | if the image is complex | |
InvalidValueException | if the shrink amount is not a non zero, positive integer | |
InvalidValueException | if any of the image dimensions are not divisible by the the shrink amount |
Implements EMAN::Processor.
Definition at line 1935 of file processor.cpp.
References accrue_median(), EMAN::EMData::copy(), copy(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageFormatException, InvalidValueException, EMAN::EMData::is_complex(), EMAN::Processor::params, EMAN::Dict::set_default(), EMAN::EMData::set_size(), and EMAN::EMData::update().
01936 { 01937 if (image->is_complex()) throw ImageFormatException("Error, the median shrink processor does not work on complex images"); 01938 01939 int shrink_factor = params.set_default("n",0); 01940 if (shrink_factor <= 1) { 01941 throw InvalidValueException(shrink_factor, 01942 "median shrink: shrink factor must > 1"); 01943 } 01944 01945 int nx = image->get_xsize(); 01946 int ny = image->get_ysize(); 01947 int nz = image->get_zsize(); 01948 01949 // if ((nx % shrink_factor != 0) || (ny % shrink_factor != 0) || (nz > 1 && (nz % shrink_factor != 0))) { 01950 // throw InvalidValueException(shrink_factor, "Image size not divisible by shrink factor"); 01951 // } 01952 01953 01954 int shrunken_nx = nx / shrink_factor; 01955 int shrunken_ny = ny / shrink_factor; 01956 int shrunken_nz = 1; 01957 if (nz > 1) shrunken_nz = nz / shrink_factor; 01958 01959 EMData* copy = image->copy(); 01960 image->set_size(shrunken_nx, shrunken_ny, shrunken_nz); 01961 accrue_median(image,copy,shrink_factor); 01962 image->update(); 01963 if( copy ) 01964 { 01965 delete copy; 01966 copy = 0; 01967 } 01968 }
const string MedianShrinkProcessor::NAME = "math.medianshrink" [static] |