Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

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

ProcessorNEW ()

Static Public Attributes

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 3368 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 2244 of file processor.cpp.

References data, EMAN::EMData::get_const_data(), EMAN::EMData::get_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), nx, ny, rdata, and EMAN::EMData::scale_pixel().

Referenced by process(), and process_inplace().

02245 {
02246         const float * const data = from->get_const_data();
02247         float* rdata = to->get_data();
02248 
02249         size_t nx = from->get_xsize();
02250         size_t ny = from->get_ysize();
02251         size_t nz = from->get_zsize();
02252         size_t nxy = nx*ny;
02253 
02254 
02255         size_t shrunken_nx = nx / shrink_factor;
02256         size_t shrunken_ny = ny / shrink_factor;
02257         size_t shrunken_nz = 1;
02258         size_t shrunken_nxy = shrunken_nx * shrunken_ny;
02259 
02260         int normalize_shrink_factor = shrink_factor * shrink_factor;
02261         int z_shrink_factor = 1;
02262 
02263         if (nz > 1) {
02264                 shrunken_nz = nz / shrink_factor;
02265                 normalize_shrink_factor *= shrink_factor;
02266                 z_shrink_factor = shrink_factor;
02267         }
02268 
02269         float invnormfactor = 1.0f/(float)normalize_shrink_factor;
02270 
02271         for (size_t k = 0; k < shrunken_nz; k++) {
02272                 size_t k_min = k * shrink_factor;
02273                 size_t k_max = k * shrink_factor + z_shrink_factor;
02274                 size_t cur_k = k * shrunken_nxy;
02275 
02276                 for (size_t j = 0; j < shrunken_ny; j++) {
02277                         size_t j_min = j * shrink_factor;
02278                         size_t j_max = j * shrink_factor + shrink_factor;
02279                         size_t cur_j = j * shrunken_nx + cur_k;
02280 
02281                         for (size_t i = 0; i < shrunken_nx; i++) {
02282                                 size_t i_min = i * shrink_factor;
02283                                 size_t i_max = i * shrink_factor + shrink_factor;
02284 
02285                                 float sum = 0;
02286                                 for (size_t kk = k_min; kk < k_max; kk++) {
02287                                         size_t cur_kk = kk * nxy;
02288 
02289                                         for (size_t jj = j_min; jj < j_max; jj++) {
02290                                                 size_t cur_jj = jj * nx + cur_kk;
02291                                                 for (size_t ii = i_min; ii < i_max; ii++) {
02292                                                         sum += data[ii + cur_jj];
02293                                                 }
02294                                         }
02295                                 }
02296                                 rdata[i + cur_j] = sum * invnormfactor;
02297                         }
02298                 }
02299         }
02300         to->scale_pixel((float)shrink_factor);
02301 }

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 2304 of file processor.cpp.

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

Referenced by process(), and process_inplace().

02305 {
02306         int nx0 = from->get_xsize(), ny0 = from->get_ysize();   // the original size
02307 
02308         int nx = to->get_xsize(), ny = to->get_ysize();
02309 
02310         float *data = to->get_data();
02311         const float * const data0 = from->get_const_data();
02312 
02313         for (int j = 0; j < ny; j++) {
02314                 int jj = int(j * 1.5);
02315                 float jw0 = 1.0F, jw1 = 0.5F;   // 3x3 -> 2x2, so each new pixel should have 2.25 of the old pixels
02316                 if ( j%2 ) {
02317                         jw0 = 0.5F;
02318                         jw1 = 1.0F;
02319                 }
02320                 for (int i = 0; i < nx; i++) {
02321                         int ii = int(i * 1.5);
02322                         float iw0 = 1.0F, iw1 = 0.5F;
02323                         float w = 0.0F;
02324 
02325                         if ( i%2 ) {
02326                                 iw0 = 0.5F;
02327                                 iw1 = 1.0F;
02328                         }
02329                         if ( jj < ny0 ) {
02330                                 if ( ii < nx0 ) {
02331                                         data[j * nx + i] = data0[ jj * nx0 + ii ] * jw0 * iw0 ;
02332                                         w += jw0 * iw0 ;
02333                                         if ( ii+1 < nx0 ) {
02334                                                 data[j * nx + i] += data0[ jj * nx0 + ii + 1] * jw0 * iw1;
02335                                                 w += jw0 * iw1;
02336                                         }
02337                                 }
02338                                 if ( jj +1 < ny0 ) {
02339                                         if ( ii < nx0 ) {
02340                                                 data[j * nx + i] += data0[ (jj+1) * nx0 + ii ] * jw1 * iw0;
02341                                                 w += jw1 * iw0;
02342                                                 if ( ii+1 < nx0 ) {
02343                                                         data[j * nx + i] += data0[ (jj+1) * nx0 + ii + 1] * jw1 * iw1;
02344                                                         w += jw1 * iw1;
02345                                                 }
02346                                         }
02347                                 }
02348                         }
02349                         if ( w>0 ) data[j * nx + i] /= w;
02350                 }
02351         }
02352 
02353         to->update();
02354         to->scale_pixel((float)1.5);
02355 }

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

03392                         {
03393                                 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03394                         }

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

03397                         {
03398                                 return NAME;
03399                         }

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

References EMAN::TypeDict::put().

03406                         {
03407                                 TypeDict d;
03408                                 d.put("n", EMObject::FLOAT, "The shrink factor");
03409                                 return d;
03410                         }

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

Definition at line 3400 of file processor.h.

03401                         {
03402                                 return new MeanShrinkProcessor();
03403                         }

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 2139 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(), nx, ny, EMAN::Dict::set_default(), EMAN::EMData::set_size(), and EMAN::EMData::update().

02140 {
02141         if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02142 
02143         if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02144 
02145         float shrink_factor0 = params.set_default("n",0.0f);
02146         int shrink_factor = int(shrink_factor0);
02147         if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02148                 throw InvalidValueException(shrink_factor0,
02149                                                                         "mean shrink: shrink factor must be >1 integer or 1.5");
02150         }
02151 
02152         int nx = image->get_xsize();
02153         int ny = image->get_ysize();
02154         int nz = image->get_zsize();
02155 
02156 
02157         // here handle the special averaging by 1.5 for 2D case
02158         if (shrink_factor0==1.5 ) {
02159                 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02160 
02161                 int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
02162                 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02163                 EMData* result = new EMData(shrunken_nx,shrunken_ny,1);
02164 
02165                 accrue_mean_one_p_five(result,image);
02166                 result->update();
02167 
02168                 return result;
02169         }
02170 
02171         int shrunken_nx = nx / shrink_factor;
02172         int shrunken_ny = ny / shrink_factor;
02173         int shrunken_nz = 1;
02174 
02175         if (nz > 1) {
02176                 shrunken_nz = nz / shrink_factor;
02177         }
02178 
02179 //      EMData* result = new EMData(shrunken_nx,shrunken_ny,shrunken_nz);
02180         EMData* result = image->copy_head();
02181         result->set_size(shrunken_nx,shrunken_ny,shrunken_nz);
02182         accrue_mean(result,image,shrink_factor);
02183 
02184         result->update();
02185 
02186         return result;
02187 }

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 2189 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(), nx, ny, EMAN::Dict::set_default(), EMAN::EMData::set_size(), EMAN::EMData::to_zero(), and EMAN::EMData::update().

02190 {
02191         if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02192 
02193         if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02194 
02195         float shrink_factor0 = params.set_default("n",0.0f);
02196         int shrink_factor = int(shrink_factor0);
02197         if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02198                 throw InvalidValueException(shrink_factor0,
02199                                                                         "mean shrink: shrink factor must be >1 integer or 1.5");
02200         }
02201 
02202 /*      if ((nx % shrink_factor != 0) || (ny % shrink_factor != 0) ||
02203         (nz > 1 && (nz % shrink_factor != 0))) {
02204         throw InvalidValueException(shrink_factor,
02205         "Image size not divisible by shrink factor");
02206 }*/
02207 
02208         int nx = image->get_xsize();
02209         int ny = image->get_ysize();
02210         int nz = image->get_zsize();
02211         // here handle the special averaging by 1.5 for 2D case
02212         if (shrink_factor0==1.5 ) {
02213                 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02214 
02215                 int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
02216                 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02217 
02218                 EMData* orig = image->copy();
02219                 image->set_size(shrunken_nx, shrunken_ny, 1);   // now nx = shrunken_nx, ny = shrunken_ny
02220                 image->to_zero();
02221 
02222                 accrue_mean_one_p_five(image,orig);
02223 
02224                 if( orig ) {
02225                         delete orig;
02226                         orig = 0;
02227                 }
02228                 image->update();
02229 
02230                 return;
02231         }
02232 
02233         accrue_mean(image,image,shrink_factor);
02234 
02235         int shrunken_nx = nx / shrink_factor;
02236         int shrunken_ny = ny / shrink_factor;
02237         int shrunken_nz = 1;
02238         if (nz > 1) shrunken_nz = nz / shrink_factor;
02239 
02240         image->update();
02241         image->set_size(shrunken_nx, shrunken_ny, shrunken_nz);
02242 }


Member Data Documentation

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

Definition at line 125 of file processor.cpp.


The documentation for this class was generated from the following files:
Generated on Mon May 2 13:30:20 2011 for EMAN2 by  doxygen 1.3.9.1