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 3406 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 2272 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().

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

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

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

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

03430                         {
03431                                 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03432                         }

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

References NAME.

03435                         {
03436                                 return NAME;
03437                         }

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

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

03444                         {
03445                                 TypeDict d;
03446                                 d.put("n", EMObject::FLOAT, "The shrink factor");
03447                                 return d;
03448                         }

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

Definition at line 3438 of file processor.h.

03439                         {
03440                                 return new MeanShrinkProcessor();
03441                         }

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

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

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

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


Member Data Documentation

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

Definition at line 3450 of file processor.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Tue Jul 12 13:49:06 2011 for EMAN2 by  doxygen 1.4.7