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 3312 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 2213 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().

02214 {
02215         const float * const data = from->get_const_data();
02216         float* rdata = to->get_data();
02217 
02218         size_t nx = from->get_xsize();
02219         size_t ny = from->get_ysize();
02220         size_t nz = from->get_zsize();
02221         size_t nxy = nx*ny;
02222 
02223 
02224         size_t shrunken_nx = nx / shrink_factor;
02225         size_t shrunken_ny = ny / shrink_factor;
02226         size_t shrunken_nz = 1;
02227         size_t shrunken_nxy = shrunken_nx * shrunken_ny;
02228 
02229         int normalize_shrink_factor = shrink_factor * shrink_factor;
02230         int z_shrink_factor = 1;
02231 
02232         if (nz > 1) {
02233                 shrunken_nz = nz / shrink_factor;
02234                 normalize_shrink_factor *= shrink_factor;
02235                 z_shrink_factor = shrink_factor;
02236         }
02237 
02238         float invnormfactor = 1.0f/(float)normalize_shrink_factor;
02239 
02240         for (size_t k = 0; k < shrunken_nz; k++) {
02241                 size_t k_min = k * shrink_factor;
02242                 size_t k_max = k * shrink_factor + z_shrink_factor;
02243                 size_t cur_k = k * shrunken_nxy;
02244 
02245                 for (size_t j = 0; j < shrunken_ny; j++) {
02246                         size_t j_min = j * shrink_factor;
02247                         size_t j_max = j * shrink_factor + shrink_factor;
02248                         size_t cur_j = j * shrunken_nx + cur_k;
02249 
02250                         for (size_t i = 0; i < shrunken_nx; i++) {
02251                                 size_t i_min = i * shrink_factor;
02252                                 size_t i_max = i * shrink_factor + shrink_factor;
02253 
02254                                 float sum = 0;
02255                                 for (size_t kk = k_min; kk < k_max; kk++) {
02256                                         size_t cur_kk = kk * nxy;
02257 
02258                                         for (size_t jj = j_min; jj < j_max; jj++) {
02259                                                 size_t cur_jj = jj * nx + cur_kk;
02260                                                 for (size_t ii = i_min; ii < i_max; ii++) {
02261                                                         sum += data[ii + cur_jj];
02262                                                 }
02263                                         }
02264                                 }
02265                                 rdata[i + cur_j] = sum * invnormfactor;
02266                         }
02267                 }
02268         }
02269         to->scale_pixel((float)shrink_factor);
02270 }

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

02274 {
02275         int nx0 = from->get_xsize(), ny0 = from->get_ysize();   // the original size
02276 
02277         int nx = to->get_xsize(), ny = to->get_ysize();
02278 
02279         float *data = to->get_data();
02280         const float * const data0 = from->get_const_data();
02281 
02282         for (int j = 0; j < ny; j++) {
02283                 int jj = int(j * 1.5);
02284                 float jw0 = 1.0F, jw1 = 0.5F;   // 3x3 -> 2x2, so each new pixel should have 2.25 of the old pixels
02285                 if ( j%2 ) {
02286                         jw0 = 0.5F;
02287                         jw1 = 1.0F;
02288                 }
02289                 for (int i = 0; i < nx; i++) {
02290                         int ii = int(i * 1.5);
02291                         float iw0 = 1.0F, iw1 = 0.5F;
02292                         float w = 0.0F;
02293 
02294                         if ( i%2 ) {
02295                                 iw0 = 0.5F;
02296                                 iw1 = 1.0F;
02297                         }
02298                         if ( jj < ny0 ) {
02299                                 if ( ii < nx0 ) {
02300                                         data[j * nx + i] = data0[ jj * nx0 + ii ] * jw0 * iw0 ;
02301                                         w += jw0 * iw0 ;
02302                                         if ( ii+1 < nx0 ) {
02303                                                 data[j * nx + i] += data0[ jj * nx0 + ii + 1] * jw0 * iw1;
02304                                                 w += jw0 * iw1;
02305                                         }
02306                                 }
02307                                 if ( jj +1 < ny0 ) {
02308                                         if ( ii < nx0 ) {
02309                                                 data[j * nx + i] += data0[ (jj+1) * nx0 + ii ] * jw1 * iw0;
02310                                                 w += jw1 * iw0;
02311                                                 if ( ii+1 < nx0 ) {
02312                                                         data[j * nx + i] += data0[ (jj+1) * nx0 + ii + 1] * jw1 * iw1;
02313                                                         w += jw1 * iw1;
02314                                                 }
02315                                         }
02316                                 }
02317                         }
02318                         if ( w>0 ) data[j * nx + i] /= w;
02319                 }
02320         }
02321 
02322         to->update();
02323         to->scale_pixel((float)1.5);
02324 }

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

03336                         {
03337                                 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03338                         }

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

03341                         {
03342                                 return NAME;
03343                         }

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

References EMAN::TypeDict::put().

03350                         {
03351                                 TypeDict d;
03352                                 d.put("n", EMObject::FLOAT, "The shrink factor");
03353                                 return d;
03354                         }

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

Definition at line 3344 of file processor.h.

03345                         {
03346                                 return new MeanShrinkProcessor();
03347                         }

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

02109 {
02110         if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02111 
02112         if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02113 
02114         float shrink_factor0 = params.set_default("n",0.0f);
02115         int shrink_factor = int(shrink_factor0);
02116         if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02117                 throw InvalidValueException(shrink_factor0,
02118                                                                         "mean shrink: shrink factor must be >1 integer or 1.5");
02119         }
02120 
02121         int nx = image->get_xsize();
02122         int ny = image->get_ysize();
02123         int nz = image->get_zsize();
02124 
02125 
02126         // here handle the special averaging by 1.5 for 2D case
02127         if (shrink_factor0==1.5 ) {
02128                 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02129 
02130                 int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
02131                 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02132                 EMData* result = new EMData(shrunken_nx,shrunken_ny,1);
02133 
02134                 accrue_mean_one_p_five(result,image);
02135                 result->update();
02136 
02137                 return result;
02138         }
02139 
02140         int shrunken_nx = nx / shrink_factor;
02141         int shrunken_ny = ny / shrink_factor;
02142         int shrunken_nz = 1;
02143 
02144         if (nz > 1) {
02145                 shrunken_nz = nz / shrink_factor;
02146         }
02147 
02148 //      EMData* result = new EMData(shrunken_nx,shrunken_ny,shrunken_nz);
02149         EMData* result = image->copy_head();
02150         result->set_size(shrunken_nx,shrunken_ny,shrunken_nz);
02151         accrue_mean(result,image,shrink_factor);
02152 
02153         result->update();
02154 
02155         return result;
02156 }

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

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


Member Data Documentation

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

Definition at line 123 of file processor.cpp.


The documentation for this class was generated from the following files:
Generated on Thu Mar 10 23:00:03 2011 for EMAN2 by  doxygen 1.3.9.1