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 3447 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 2283 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().

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

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

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

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

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

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

03476                         {
03477                                 return NAME;
03478                         }

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

References EMAN::TypeDict::put().

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

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

Definition at line 3479 of file processor.h.

03480                         {
03481                                 return new MeanShrinkProcessor();
03482                         }

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

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

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

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


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 Fri Aug 10 16:37:44 2012 for EMAN2 by  doxygen 1.3.9.1