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 3449 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 2285 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().

02286 {
02287         const float * const data = from->get_const_data();
02288         float* rdata = to->get_data();
02289 
02290         size_t nx = from->get_xsize();
02291         size_t ny = from->get_ysize();
02292         size_t nz = from->get_zsize();
02293         size_t nxy = nx*ny;
02294 
02295 
02296         size_t shrunken_nx = nx / shrink_factor;
02297         size_t shrunken_ny = ny / shrink_factor;
02298         size_t shrunken_nz = 1;
02299         size_t shrunken_nxy = shrunken_nx * shrunken_ny;
02300 
02301         int normalize_shrink_factor = shrink_factor * shrink_factor;
02302         int z_shrink_factor = 1;
02303 
02304         if (nz > 1) {
02305                 shrunken_nz = nz / shrink_factor;
02306                 normalize_shrink_factor *= shrink_factor;
02307                 z_shrink_factor = shrink_factor;
02308         }
02309 
02310         float invnormfactor = 1.0f/(float)normalize_shrink_factor;
02311 
02312         for (size_t k = 0; k < shrunken_nz; k++) {
02313                 size_t k_min = k * shrink_factor;
02314                 size_t k_max = k * shrink_factor + z_shrink_factor;
02315                 size_t cur_k = k * shrunken_nxy;
02316 
02317                 for (size_t j = 0; j < shrunken_ny; j++) {
02318                         size_t j_min = j * shrink_factor;
02319                         size_t j_max = j * shrink_factor + shrink_factor;
02320                         size_t cur_j = j * shrunken_nx + cur_k;
02321 
02322                         for (size_t i = 0; i < shrunken_nx; i++) {
02323                                 size_t i_min = i * shrink_factor;
02324                                 size_t i_max = i * shrink_factor + shrink_factor;
02325 
02326                                 float sum = 0;
02327                                 for (size_t kk = k_min; kk < k_max; kk++) {
02328                                         size_t cur_kk = kk * nxy;
02329 
02330                                         for (size_t jj = j_min; jj < j_max; jj++) {
02331                                                 size_t cur_jj = jj * nx + cur_kk;
02332                                                 for (size_t ii = i_min; ii < i_max; ii++) {
02333                                                         sum += data[ii + cur_jj];
02334                                                 }
02335                                         }
02336                                 }
02337                                 rdata[i + cur_j] = sum * invnormfactor;
02338                         }
02339                 }
02340         }
02341         to->scale_pixel((float)shrink_factor);
02342 }

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

02346 {
02347         int nx0 = from->get_xsize(), ny0 = from->get_ysize();   // the original size
02348 
02349         int nx = to->get_xsize(), ny = to->get_ysize();
02350 
02351         float *data = to->get_data();
02352         const float * const data0 = from->get_const_data();
02353 
02354         for (int j = 0; j < ny; j++) {
02355                 int jj = int(j * 1.5);
02356                 float jw0 = 1.0F, jw1 = 0.5F;   // 3x3 -> 2x2, so each new pixel should have 2.25 of the old pixels
02357                 if ( j%2 ) {
02358                         jw0 = 0.5F;
02359                         jw1 = 1.0F;
02360                 }
02361                 for (int i = 0; i < nx; i++) {
02362                         int ii = int(i * 1.5);
02363                         float iw0 = 1.0F, iw1 = 0.5F;
02364                         float w = 0.0F;
02365 
02366                         if ( i%2 ) {
02367                                 iw0 = 0.5F;
02368                                 iw1 = 1.0F;
02369                         }
02370                         if ( jj < ny0 ) {
02371                                 if ( ii < nx0 ) {
02372                                         data[j * nx + i] = data0[ jj * nx0 + ii ] * jw0 * iw0 ;
02373                                         w += jw0 * iw0 ;
02374                                         if ( ii+1 < nx0 ) {
02375                                                 data[j * nx + i] += data0[ jj * nx0 + ii + 1] * jw0 * iw1;
02376                                                 w += jw0 * iw1;
02377                                         }
02378                                 }
02379                                 if ( jj +1 < ny0 ) {
02380                                         if ( ii < nx0 ) {
02381                                                 data[j * nx + i] += data0[ (jj+1) * nx0 + ii ] * jw1 * iw0;
02382                                                 w += jw1 * iw0;
02383                                                 if ( ii+1 < nx0 ) {
02384                                                         data[j * nx + i] += data0[ (jj+1) * nx0 + ii + 1] * jw1 * iw1;
02385                                                         w += jw1 * iw1;
02386                                                 }
02387                                         }
02388                                 }
02389                         }
02390                         if ( w>0 ) data[j * nx + i] /= w;
02391                 }
02392         }
02393 
02394         to->update();
02395         to->scale_pixel((float)1.5);
02396 }

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

03473                         {
03474                                 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03475                         }

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

03478                         {
03479                                 return NAME;
03480                         }

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

References EMAN::TypeDict::put().

03487                         {
03488                                 TypeDict d;
03489                                 d.put("n", EMObject::FLOAT, "The shrink factor");
03490                                 return d;
03491                         }

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

Definition at line 3481 of file processor.h.

03482                         {
03483                                 return new MeanShrinkProcessor();
03484                         }

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

02181 {
02182         if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02183 
02184         if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02185 
02186         float shrink_factor0 = params.set_default("n",0.0f);
02187         int shrink_factor = int(shrink_factor0);
02188         if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02189                 throw InvalidValueException(shrink_factor0,
02190                                                                         "mean shrink: shrink factor must be >1 integer or 1.5");
02191         }
02192 
02193         int nx = image->get_xsize();
02194         int ny = image->get_ysize();
02195         int nz = image->get_zsize();
02196 
02197 
02198         // here handle the special averaging by 1.5 for 2D case
02199         if (shrink_factor0==1.5 ) {
02200                 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02201 
02202                 int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
02203                 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02204                 EMData* result = new EMData(shrunken_nx,shrunken_ny,1);
02205 
02206                 accrue_mean_one_p_five(result,image);
02207                 result->update();
02208 
02209                 return result;
02210         }
02211 
02212         int shrunken_nx = nx / shrink_factor;
02213         int shrunken_ny = ny / shrink_factor;
02214         int shrunken_nz = 1;
02215 
02216         if (nz > 1) {
02217                 shrunken_nz = nz / shrink_factor;
02218         }
02219 
02220 //      EMData* result = new EMData(shrunken_nx,shrunken_ny,shrunken_nz);
02221         EMData* result = image->copy_head();
02222         result->set_size(shrunken_nx,shrunken_ny,shrunken_nz);
02223         accrue_mean(result,image,shrink_factor);
02224 
02225         result->update();
02226 
02227         return result;
02228 }

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

02231 {
02232         if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02233 
02234         if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02235 
02236         float shrink_factor0 = params.set_default("n",0.0f);
02237         int shrink_factor = int(shrink_factor0);
02238         if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02239                 throw InvalidValueException(shrink_factor0,
02240                                                                         "mean shrink: shrink factor must be >1 integer or 1.5");
02241         }
02242 
02243 /*      if ((nx % shrink_factor != 0) || (ny % shrink_factor != 0) ||
02244         (nz > 1 && (nz % shrink_factor != 0))) {
02245         throw InvalidValueException(shrink_factor,
02246         "Image size not divisible by shrink factor");
02247 }*/
02248 
02249         int nx = image->get_xsize();
02250         int ny = image->get_ysize();
02251         int nz = image->get_zsize();
02252         // here handle the special averaging by 1.5 for 2D case
02253         if (shrink_factor0==1.5 ) {
02254                 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02255 
02256                 int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
02257                 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02258 
02259                 EMData* orig = image->copy();
02260                 image->set_size(shrunken_nx, shrunken_ny, 1);   // now nx = shrunken_nx, ny = shrunken_ny
02261                 image->to_zero();
02262 
02263                 accrue_mean_one_p_five(image,orig);
02264 
02265                 if( orig ) {
02266                         delete orig;
02267                         orig = 0;
02268                 }
02269                 image->update();
02270 
02271                 return;
02272         }
02273 
02274         accrue_mean(image,image,shrink_factor);
02275 
02276         int shrunken_nx = nx / shrink_factor;
02277         int shrunken_ny = ny / shrink_factor;
02278         int shrunken_nz = 1;
02279         if (nz > 1) shrunken_nz = nz / shrink_factor;
02280 
02281         image->update();
02282         image->set_size(shrunken_nx, shrunken_ny, shrunken_nz);
02283 }


Member Data Documentation

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

Definition at line 126 of file processor.cpp.


The documentation for this class was generated from the following files:
Generated on Tue Jun 11 13:48:44 2013 for EMAN2 by  doxygen 1.3.9.1