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:

[legend]
Collaboration diagram for EMAN::MeanShrinkProcessor:
[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 3403 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 2197 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().

02198 {
02199         const float * const data = from->get_const_data();
02200         float* rdata = to->get_data();
02201 
02202         int nx = from->get_xsize();
02203         int ny = from->get_ysize();
02204         int nz = from->get_zsize();
02205         int nxy = nx*ny;
02206 
02207 
02208         int shrunken_nx = nx / shrink_factor;
02209         int shrunken_ny = ny / shrink_factor;
02210         int shrunken_nz = 1;
02211         int shrunken_nxy = shrunken_nx * shrunken_ny;
02212 
02213         int normalize_shrink_factor = shrink_factor * shrink_factor;
02214         int z_shrink_factor = 1;
02215 
02216         if (nz > 1) {
02217                 shrunken_nz = nz / shrink_factor;
02218                 normalize_shrink_factor *= shrink_factor;
02219                 z_shrink_factor = shrink_factor;
02220         }
02221 
02222         float invnormfactor = 1.0f/(float)normalize_shrink_factor;
02223 
02224         for (int k = 0; k < shrunken_nz; k++) {
02225                 int k_min = k * shrink_factor;
02226                 int k_max = k * shrink_factor + z_shrink_factor;
02227                 size_t cur_k = k * shrunken_nxy;
02228 
02229                 for (int j = 0; j < shrunken_ny; j++) {
02230                         int j_min = j * shrink_factor;
02231                         int j_max = j * shrink_factor + shrink_factor;
02232                         size_t cur_j = j * shrunken_nx + cur_k;
02233 
02234                         for (int i = 0; i < shrunken_nx; i++) {
02235                                 int i_min = i * shrink_factor;
02236                                 int i_max = i * shrink_factor + shrink_factor;
02237 
02238                                 float sum = 0;
02239                                 for (int kk = k_min; kk < k_max; kk++) {
02240                                         size_t cur_kk = kk * nxy;
02241 
02242                                         for (int jj = j_min; jj < j_max; jj++) {
02243                                                 size_t cur_jj = jj * nx + cur_kk;
02244                                                 for (int ii = i_min; ii < i_max; ii++) {
02245                                                         sum += data[ii + cur_jj];
02246                                                 }
02247                                         }
02248                                 }
02249                                 rdata[i + cur_j] = sum * invnormfactor;
02250                         }
02251                 }
02252         }
02253         to->scale_pixel((float)shrink_factor);
02254 }

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

02258 {
02259         int nx0 = from->get_xsize(), ny0 = from->get_ysize();   // the original size
02260 
02261         int nx = to->get_xsize(), ny = to->get_ysize();
02262 
02263         float *data = to->get_data();
02264         const float * const data0 = from->get_const_data();
02265 
02266         for (int j = 0; j < ny; j++) {
02267                 int jj = int(j * 1.5);
02268                 float jw0 = 1.0F, jw1 = 0.5F;   // 3x3 -> 2x2, so each new pixel should have 2.25 of the old pixels
02269                 if ( j%2 ) {
02270                         jw0 = 0.5F;
02271                         jw1 = 1.0F;
02272                 }
02273                 for (int i = 0; i < nx; i++) {
02274                         int ii = int(i * 1.5);
02275                         float iw0 = 1.0F, iw1 = 0.5F;
02276                         float w = 0.0F;
02277 
02278                         if ( i%2 ) {
02279                                 iw0 = 0.5F;
02280                                 iw1 = 1.0F;
02281                         }
02282                         if ( jj < ny0 ) {
02283                                 if ( ii < nx0 ) {
02284                                         data[j * nx + i] = data0[ jj * nx0 + ii ] * jw0 * iw0 ;
02285                                         w += jw0 * iw0 ;
02286                                         if ( ii+1 < nx0 ) {
02287                                                 data[j * nx + i] += data0[ jj * nx0 + ii + 1] * jw0 * iw1;
02288                                                 w += jw0 * iw1;
02289                                         }
02290                                 }
02291                                 if ( jj +1 < ny0 ) {
02292                                         if ( ii < nx0 ) {
02293                                                 data[j * nx + i] += data0[ (jj+1) * nx0 + ii ] * jw1 * iw0;
02294                                                 w += jw1 * iw0;
02295                                                 if ( ii+1 < nx0 ) {
02296                                                         data[j * nx + i] += data0[ (jj+1) * nx0 + ii + 1] * jw1 * iw1;
02297                                                         w += jw1 * iw1;
02298                                                 }
02299                                         }
02300                                 }
02301                         }
02302                         if ( w>0 ) data[j * nx + i] /= w;
02303                 }
02304         }
02305 
02306         to->update();
02307         to->scale_pixel((float)1.5);
02308 }

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

03427                         {
03428                                 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03429                         }

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

03432                         {
03433                                 return NAME;
03434                         }

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

References EMAN::TypeDict::put().

03441                         {
03442                                 TypeDict d;
03443                                 d.put("n", EMObject::FLOAT, "The shrink factor");
03444                                 return d;
03445                         }

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

Definition at line 3435 of file processor.h.

03436                         {
03437                                 return new MeanShrinkProcessor();
03438                         }

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

02093 {
02094         if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02095 
02096         if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02097 
02098         float shrink_factor0 = params.set_default("n",0.0f);
02099         int shrink_factor = int(shrink_factor0);
02100         if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02101                 throw InvalidValueException(shrink_factor0,
02102                                                                         "mean shrink: shrink factor must be >1 integer or 1.5");
02103         }
02104 
02105         int nx = image->get_xsize();
02106         int ny = image->get_ysize();
02107         int nz = image->get_zsize();
02108 
02109 
02110         // here handle the special averaging by 1.5 for 2D case
02111         if (shrink_factor0==1.5 ) {
02112                 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02113 
02114                 int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
02115                 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02116                 EMData* result = new EMData(shrunken_nx,shrunken_ny,1);
02117 
02118                 accrue_mean_one_p_five(result,image);
02119                 result->update();
02120 
02121                 return result;
02122         }
02123 
02124         int shrunken_nx = nx / shrink_factor;
02125         int shrunken_ny = ny / shrink_factor;
02126         int shrunken_nz = 1;
02127 
02128         if (nz > 1) {
02129                 shrunken_nz = nz / shrink_factor;
02130         }
02131 
02132 //      EMData* result = new EMData(shrunken_nx,shrunken_ny,shrunken_nz);
02133         EMData* result = image->copy_head();
02134         result->set_size(shrunken_nx,shrunken_ny,shrunken_nz);
02135         accrue_mean(result,image,shrink_factor);
02136 
02137         result->update();
02138 
02139         return result;
02140 }

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

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


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 Fri Apr 30 15:39:22 2010 for EMAN2 by  doxygen 1.3.9.1