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

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

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

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

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.

References NAME.

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::EMObject::FLOAT, and EMAN::TypeDict::put().

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

static 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 2174 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().

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

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

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


Member Data Documentation

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

Definition at line 3491 of file processor.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Thu May 3 10:10:12 2012 for EMAN2 by  doxygen 1.4.7