EMAN::MeanShrinkProcessor Class Reference

MeanShrinkProcessor shrinks an image by in an integer amount (and optionally by 1.5) taking the mean of the pixel neighbourhood. More...

#include <processor.h>

Inheritance diagram for EMAN::MeanShrinkProcessor:

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

Collaboration graph
[legend]

List of all members.

Public Member Functions

virtual EMDataprocess (const EMData *const image)
 The meanshrink 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)
 Mean shrink inplace.
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 ProcessorNEW ()

Static Public Attributes

static const string NAME = "math.meanshrink"

Private Member Functions

void accrue_mean (EMData *to, const EMData *const from, const int shrinkfactor)
 Accrue the local mean 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.
void accrue_mean_one_p_five (EMData *to, const EMData *const from)
 Accrue the local mean in the image 'from' to the image 'to' using the the special case shrink factor of 1.5 This is an internal function that encapsulates a routine common to both process and process inplace.


Detailed Description

MeanShrinkProcessor shrinks an image by in an integer amount (and optionally by 1.5) taking the mean of the pixel neighbourhood.

Author:
David Woolford (But is basically a copy of the old EMData::mean_shrink, probably written by Steven Ludtke )
Date:
May 2008
Parameters:
n The shrink factor

Definition at line 3343 of file processor.h.


Member Function Documentation

EMData * MeanShrinkProcessor::process ( const EMData *const   image  )  [virtual]

The meanshrink 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

Parameters:
image the image that will be used to generate a 'mean shrunken' image
Exceptions:
ImageFormatException if the image is complex
ImageDimensionException if the image is 1D
InvalidValueException if the shrink amount is a nonzero integer, unless it is 1.5, which is an exceptional circumstance

Reimplemented from EMAN::Processor.

Definition at line 2029 of file processor.cpp.

References accrue_mean(), accrue_mean_one_p_five(), EMAN::EMData::copy_head(), EMAN::EMData::get_ndim(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageDimensionException, ImageFormatException, InvalidValueException, EMAN::EMData::is_complex(), EMAN::Processor::params, EMAN::Dict::set_default(), EMAN::EMData::set_size(), and EMAN::EMData::update().

02030 {
02031         if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02032 
02033         if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02034 
02035         float shrink_factor0 = params.set_default("n",0.0f);
02036         int shrink_factor = int(shrink_factor0);
02037         if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02038                 throw InvalidValueException(shrink_factor0,
02039                                                                         "mean shrink: shrink factor must be >1 integer or 1.5");
02040         }
02041 
02042         int nx = image->get_xsize();
02043         int ny = image->get_ysize();
02044         int nz = image->get_zsize();
02045 
02046 
02047         // here handle the special averaging by 1.5 for 2D case
02048         if (shrink_factor0==1.5 ) {
02049                 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02050 
02051                 int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
02052                 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02053                 EMData* result = new EMData(shrunken_nx,shrunken_ny,1);
02054 
02055                 accrue_mean_one_p_five(result,image);
02056                 result->update();
02057 
02058                 return result;
02059         }
02060 
02061         int shrunken_nx = nx / shrink_factor;
02062         int shrunken_ny = ny / shrink_factor;
02063         int shrunken_nz = 1;
02064 
02065         if (nz > 1) {
02066                 shrunken_nz = nz / shrink_factor;
02067         }
02068 
02069 //      EMData* result = new EMData(shrunken_nx,shrunken_ny,shrunken_nz);
02070         EMData* result = image->copy_head();
02071         result->set_size(shrunken_nx,shrunken_ny,shrunken_nz);
02072         accrue_mean(result,image,shrink_factor);
02073 
02074         result->update();
02075 
02076         return result;
02077 }

void MeanShrinkProcessor::process_inplace ( EMData image  )  [virtual]

Mean shrink inplace.

Parameters:
image the image that will be 'mean shrunken' inplace
Exceptions:
ImageFormatException if the image is complex
ImageDimensionException if the image is 1D
InvalidValueException if the shrink amount is a nonzero integer, unless it is 1.5, which is an exceptional circumstance

Implements EMAN::Processor.

Definition at line 2079 of file processor.cpp.

References accrue_mean(), accrue_mean_one_p_five(), EMAN::EMData::copy(), EMAN::EMData::get_ndim(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageDimensionException, ImageFormatException, InvalidValueException, EMAN::EMData::is_complex(), EMAN::Processor::params, EMAN::Dict::set_default(), EMAN::EMData::set_size(), EMAN::EMData::to_zero(), and EMAN::EMData::update().

02080 {
02081         if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02082 
02083         if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02084 
02085         float shrink_factor0 = params.set_default("n",0.0f);
02086         int shrink_factor = int(shrink_factor0);
02087         if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02088                 throw InvalidValueException(shrink_factor0,
02089                                                                         "mean shrink: shrink factor must be >1 integer or 1.5");
02090         }
02091 
02092 /*      if ((nx % shrink_factor != 0) || (ny % shrink_factor != 0) ||
02093         (nz > 1 && (nz % shrink_factor != 0))) {
02094         throw InvalidValueException(shrink_factor,
02095         "Image size not divisible by shrink factor");
02096 }*/
02097 
02098         int nx = image->get_xsize();
02099         int ny = image->get_ysize();
02100         int nz = image->get_zsize();
02101         // here handle the special averaging by 1.5 for 2D case
02102         if (shrink_factor0==1.5 ) {
02103                 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02104 
02105                 int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
02106                 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02107 
02108                 EMData* orig = image->copy();
02109                 image->set_size(shrunken_nx, shrunken_ny, 1);   // now nx = shrunken_nx, ny = shrunken_ny
02110                 image->to_zero();
02111 
02112                 accrue_mean_one_p_five(image,orig);
02113 
02114                 if( orig ) {
02115                         delete orig;
02116                         orig = 0;
02117                 }
02118                 image->update();
02119 
02120                 return;
02121         }
02122 
02123         accrue_mean(image,image,shrink_factor);
02124 
02125         int shrunken_nx = nx / shrink_factor;
02126         int shrunken_ny = ny / shrink_factor;
02127         int shrunken_nz = 1;
02128         if (nz > 1) shrunken_nz = nz / shrink_factor;
02129 
02130         image->update();
02131         image->set_size(shrunken_nx, shrunken_ny, shrunken_nz);
02132 }

string EMAN::MeanShrinkProcessor::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 3366 of file processor.h.

03367                         {
03368                                 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03369                         }

virtual string EMAN::MeanShrinkProcessor::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 3371 of file processor.h.

References NAME.

03372                         {
03373                                 return NAME;
03374                         }

static Processor* EMAN::MeanShrinkProcessor::NEW (  )  [inline, static]

Definition at line 3375 of file processor.h.

03376                         {
03377                                 return new MeanShrinkProcessor();
03378                         }

virtual TypeDict EMAN::MeanShrinkProcessor::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 3380 of file processor.h.

References EMAN::EMObject::FLOAT, and EMAN::TypeDict::put().

03381                         {
03382                                 TypeDict d;
03383                                 d.put("n", EMObject::FLOAT, "The shrink factor");
03384                                 return d;
03385                         }

void MeanShrinkProcessor::accrue_mean ( EMData to,
const EMData *const   from,
const int  shrinkfactor 
) [private]

Accrue the local mean 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.

Parameters:
to the smaller image that will store the mean values
from the larger image that will be used to calculate the mean values
shrinkfactor the shrink amount

Definition at line 2134 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().

02135 {
02136         const float * const data = from->get_const_data();
02137         float* rdata = to->get_data();
02138 
02139         int nx = from->get_xsize();
02140         int ny = from->get_ysize();
02141         int nz = from->get_zsize();
02142         int nxy = nx*ny;
02143 
02144 
02145         int shrunken_nx = nx / shrink_factor;
02146         int shrunken_ny = ny / shrink_factor;
02147         int shrunken_nz = 1;
02148         int shrunken_nxy = shrunken_nx * shrunken_ny;
02149 
02150         int normalize_shrink_factor = shrink_factor * shrink_factor;
02151         int z_shrink_factor = 1;
02152 
02153         if (nz > 1) {
02154                 shrunken_nz = nz / shrink_factor;
02155                 normalize_shrink_factor *= shrink_factor;
02156                 z_shrink_factor = shrink_factor;
02157         }
02158 
02159         float invnormfactor = 1.0f/(float)normalize_shrink_factor;
02160 
02161         for (int k = 0; k < shrunken_nz; k++) {
02162                 int k_min = k * shrink_factor;
02163                 int k_max = k * shrink_factor + z_shrink_factor;
02164                 size_t cur_k = k * shrunken_nxy;
02165 
02166                 for (int j = 0; j < shrunken_ny; j++) {
02167                         int j_min = j * shrink_factor;
02168                         int j_max = j * shrink_factor + shrink_factor;
02169                         size_t cur_j = j * shrunken_nx + cur_k;
02170 
02171                         for (int i = 0; i < shrunken_nx; i++) {
02172                                 int i_min = i * shrink_factor;
02173                                 int i_max = i * shrink_factor + shrink_factor;
02174 
02175                                 float sum = 0;
02176                                 for (int kk = k_min; kk < k_max; kk++) {
02177                                         size_t cur_kk = kk * nxy;
02178 
02179                                         for (int jj = j_min; jj < j_max; jj++) {
02180                                                 size_t cur_jj = jj * nx + cur_kk;
02181                                                 for (int ii = i_min; ii < i_max; ii++) {
02182                                                         sum += data[ii + cur_jj];
02183                                                 }
02184                                         }
02185                                 }
02186                                 rdata[i + cur_j] = sum * invnormfactor;
02187                         }
02188                 }
02189         }
02190         to->scale_pixel((float)shrink_factor);
02191 }

void MeanShrinkProcessor::accrue_mean_one_p_five ( EMData to,
const EMData *const   from 
) [private]

Accrue the local mean in the image 'from' to the image 'to' using the the special case shrink factor of 1.5 This is an internal function that encapsulates a routine common to both process and process inplace.

Parameters:
to the smaller image that will store the mean values
from the larger image that will be used to calculate the mean values

Definition at line 2194 of file processor.cpp.

References EMAN::EMData::get_const_data(), EMAN::EMData::get_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::scale_pixel(), and EMAN::EMData::update().

Referenced by process(), and process_inplace().

02195 {
02196         int nx0 = from->get_xsize(), ny0 = from->get_ysize();   // the original size
02197 
02198         int nx = to->get_xsize(), ny = to->get_ysize();
02199 
02200         float *data = to->get_data();
02201         const float * const data0 = from->get_const_data();
02202 
02203         for (int j = 0; j < ny; j++) {
02204                 int jj = int(j * 1.5);
02205                 float jw0 = 1.0F, jw1 = 0.5F;   // 3x3 -> 2x2, so each new pixel should have 2.25 of the old pixels
02206                 if ( j%2 ) {
02207                         jw0 = 0.5F;
02208                         jw1 = 1.0F;
02209                 }
02210                 for (int i = 0; i < nx; i++) {
02211                         int ii = int(i * 1.5);
02212                         float iw0 = 1.0F, iw1 = 0.5F;
02213                         float w = 0.0F;
02214 
02215                         if ( i%2 ) {
02216                                 iw0 = 0.5F;
02217                                 iw1 = 1.0F;
02218                         }
02219                         if ( jj < ny0 ) {
02220                                 if ( ii < nx0 ) {
02221                                         data[j * nx + i] = data0[ jj * nx0 + ii ] * jw0 * iw0 ;
02222                                         w += jw0 * iw0 ;
02223                                         if ( ii+1 < nx0 ) {
02224                                                 data[j * nx + i] += data0[ jj * nx0 + ii + 1] * jw0 * iw1;
02225                                                 w += jw0 * iw1;
02226                                         }
02227                                 }
02228                                 if ( jj +1 < ny0 ) {
02229                                         if ( ii < nx0 ) {
02230                                                 data[j * nx + i] += data0[ (jj+1) * nx0 + ii ] * jw1 * iw0;
02231                                                 w += jw1 * iw0;
02232                                                 if ( ii+1 < nx0 ) {
02233                                                         data[j * nx + i] += data0[ (jj+1) * nx0 + ii + 1] * jw1 * iw1;
02234                                                         w += jw1 * iw1;
02235                                                 }
02236                                         }
02237                                 }
02238                         }
02239                         if ( w>0 ) data[j * nx + i] /= w;
02240                 }
02241         }
02242 
02243         to->update();
02244         to->scale_pixel((float)1.5);
02245 }


Member Data Documentation

const string MeanShrinkProcessor::NAME = "math.meanshrink" [static]

Definition at line 3387 of file processor.h.

Referenced by get_name().


The documentation for this class was generated from the following files:

Generated on Thu Mar 18 02:20:43 2010 for EMAN2 by  doxygen 1.5.6