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 3402 of file processor.h.


Member Function Documentation

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 2207 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().

02208 {
02209         const float * const data = from->get_const_data();
02210         float* rdata = to->get_data();
02211 
02212         size_t nx = from->get_xsize();
02213         size_t ny = from->get_ysize();
02214         size_t nz = from->get_zsize();
02215         size_t nxy = nx*ny;
02216 
02217 
02218         size_t shrunken_nx = nx / shrink_factor;
02219         size_t shrunken_ny = ny / shrink_factor;
02220         size_t shrunken_nz = 1;
02221         size_t shrunken_nxy = shrunken_nx * shrunken_ny;
02222 
02223         int normalize_shrink_factor = shrink_factor * shrink_factor;
02224         int z_shrink_factor = 1;
02225 
02226         if (nz > 1) {
02227                 shrunken_nz = nz / shrink_factor;
02228                 normalize_shrink_factor *= shrink_factor;
02229                 z_shrink_factor = shrink_factor;
02230         }
02231 
02232         float invnormfactor = 1.0f/(float)normalize_shrink_factor;
02233 
02234         for (size_t k = 0; k < shrunken_nz; k++) {
02235                 size_t k_min = k * shrink_factor;
02236                 size_t k_max = k * shrink_factor + z_shrink_factor;
02237                 size_t cur_k = k * shrunken_nxy;
02238 
02239                 for (size_t j = 0; j < shrunken_ny; j++) {
02240                         size_t j_min = j * shrink_factor;
02241                         size_t j_max = j * shrink_factor + shrink_factor;
02242                         size_t cur_j = j * shrunken_nx + cur_k;
02243 
02244                         for (size_t i = 0; i < shrunken_nx; i++) {
02245                                 size_t i_min = i * shrink_factor;
02246                                 size_t i_max = i * shrink_factor + shrink_factor;
02247 
02248                                 float sum = 0;
02249                                 for (size_t kk = k_min; kk < k_max; kk++) {
02250                                         size_t cur_kk = kk * nxy;
02251 
02252                                         for (size_t jj = j_min; jj < j_max; jj++) {
02253                                                 size_t cur_jj = jj * nx + cur_kk;
02254                                                 for (size_t ii = i_min; ii < i_max; ii++) {
02255                                                         sum += data[ii + cur_jj];
02256                                                 }
02257                                         }
02258                                 }
02259                                 rdata[i + cur_j] = sum * invnormfactor;
02260                         }
02261                 }
02262         }
02263         to->scale_pixel((float)shrink_factor);
02264 }

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 2267 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().

02268 {
02269         int nx0 = from->get_xsize(), ny0 = from->get_ysize();   // the original size
02270 
02271         int nx = to->get_xsize(), ny = to->get_ysize();
02272 
02273         float *data = to->get_data();
02274         const float * const data0 = from->get_const_data();
02275 
02276         for (int j = 0; j < ny; j++) {
02277                 int jj = int(j * 1.5);
02278                 float jw0 = 1.0F, jw1 = 0.5F;   // 3x3 -> 2x2, so each new pixel should have 2.25 of the old pixels
02279                 if ( j%2 ) {
02280                         jw0 = 0.5F;
02281                         jw1 = 1.0F;
02282                 }
02283                 for (int i = 0; i < nx; i++) {
02284                         int ii = int(i * 1.5);
02285                         float iw0 = 1.0F, iw1 = 0.5F;
02286                         float w = 0.0F;
02287 
02288                         if ( i%2 ) {
02289                                 iw0 = 0.5F;
02290                                 iw1 = 1.0F;
02291                         }
02292                         if ( jj < ny0 ) {
02293                                 if ( ii < nx0 ) {
02294                                         data[j * nx + i] = data0[ jj * nx0 + ii ] * jw0 * iw0 ;
02295                                         w += jw0 * iw0 ;
02296                                         if ( ii+1 < nx0 ) {
02297                                                 data[j * nx + i] += data0[ jj * nx0 + ii + 1] * jw0 * iw1;
02298                                                 w += jw0 * iw1;
02299                                         }
02300                                 }
02301                                 if ( jj +1 < ny0 ) {
02302                                         if ( ii < nx0 ) {
02303                                                 data[j * nx + i] += data0[ (jj+1) * nx0 + ii ] * jw1 * iw0;
02304                                                 w += jw1 * iw0;
02305                                                 if ( ii+1 < nx0 ) {
02306                                                         data[j * nx + i] += data0[ (jj+1) * nx0 + ii + 1] * jw1 * iw1;
02307                                                         w += jw1 * iw1;
02308                                                 }
02309                                         }
02310                                 }
02311                         }
02312                         if ( w>0 ) data[j * nx + i] /= w;
02313                 }
02314         }
02315 
02316         to->update();
02317         to->scale_pixel((float)1.5);
02318 }

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 3425 of file processor.h.

03426                         {
03427                                 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03428                         }

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 3430 of file processor.h.

References NAME.

03431                         {
03432                                 return NAME;
03433                         }

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 3439 of file processor.h.

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

03440                         {
03441                                 TypeDict d;
03442                                 d.put("n", EMObject::FLOAT, "The shrink factor");
03443                                 return d;
03444                         }

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

Definition at line 3434 of file processor.h.

03435                         {
03436                                 return new MeanShrinkProcessor();
03437                         }

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 2102 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().

02103 {
02104         if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02105 
02106         if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02107 
02108         float shrink_factor0 = params.set_default("n",0.0f);
02109         int shrink_factor = int(shrink_factor0);
02110         if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02111                 throw InvalidValueException(shrink_factor0,
02112                                                                         "mean shrink: shrink factor must be >1 integer or 1.5");
02113         }
02114 
02115         int nx = image->get_xsize();
02116         int ny = image->get_ysize();
02117         int nz = image->get_zsize();
02118 
02119 
02120         // here handle the special averaging by 1.5 for 2D case
02121         if (shrink_factor0==1.5 ) {
02122                 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02123 
02124                 int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
02125                 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02126                 EMData* result = new EMData(shrunken_nx,shrunken_ny,1);
02127 
02128                 accrue_mean_one_p_five(result,image);
02129                 result->update();
02130 
02131                 return result;
02132         }
02133 
02134         int shrunken_nx = nx / shrink_factor;
02135         int shrunken_ny = ny / shrink_factor;
02136         int shrunken_nz = 1;
02137 
02138         if (nz > 1) {
02139                 shrunken_nz = nz / shrink_factor;
02140         }
02141 
02142 //      EMData* result = new EMData(shrunken_nx,shrunken_ny,shrunken_nz);
02143         EMData* result = image->copy_head();
02144         result->set_size(shrunken_nx,shrunken_ny,shrunken_nz);
02145         accrue_mean(result,image,shrink_factor);
02146 
02147         result->update();
02148 
02149         return result;
02150 }

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 2152 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().

02153 {
02154         if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02155 
02156         if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02157 
02158         float shrink_factor0 = params.set_default("n",0.0f);
02159         int shrink_factor = int(shrink_factor0);
02160         if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02161                 throw InvalidValueException(shrink_factor0,
02162                                                                         "mean shrink: shrink factor must be >1 integer or 1.5");
02163         }
02164 
02165 /*      if ((nx % shrink_factor != 0) || (ny % shrink_factor != 0) ||
02166         (nz > 1 && (nz % shrink_factor != 0))) {
02167         throw InvalidValueException(shrink_factor,
02168         "Image size not divisible by shrink factor");
02169 }*/
02170 
02171         int nx = image->get_xsize();
02172         int ny = image->get_ysize();
02173         int nz = image->get_zsize();
02174         // here handle the special averaging by 1.5 for 2D case
02175         if (shrink_factor0==1.5 ) {
02176                 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02177 
02178                 int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
02179                 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02180 
02181                 EMData* orig = image->copy();
02182                 image->set_size(shrunken_nx, shrunken_ny, 1);   // now nx = shrunken_nx, ny = shrunken_ny
02183                 image->to_zero();
02184 
02185                 accrue_mean_one_p_five(image,orig);
02186 
02187                 if( orig ) {
02188                         delete orig;
02189                         orig = 0;
02190                 }
02191                 image->update();
02192 
02193                 return;
02194         }
02195 
02196         accrue_mean(image,image,shrink_factor);
02197 
02198         int shrunken_nx = nx / shrink_factor;
02199         int shrunken_ny = ny / shrink_factor;
02200         int shrunken_nz = 1;
02201         if (nz > 1) shrunken_nz = nz / shrink_factor;
02202 
02203         image->update();
02204         image->set_size(shrunken_nx, shrunken_ny, shrunken_nz);
02205 }


Member Data Documentation

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

Definition at line 3446 of file processor.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Thu Nov 17 12:46:22 2011 for EMAN2 by  doxygen 1.4.7