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

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 3443 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 2304 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().

02305 {
02306         const float * const data = from->get_const_data();
02307         float* rdata = to->get_data();
02308 
02309         int nx = from->get_xsize();
02310         int ny = from->get_ysize();
02311         int nz = from->get_zsize();
02312         int nxy = nx*ny;
02313 
02314 
02315         int shrunken_nx = nx / shrink_factor;
02316         int shrunken_ny = ny / shrink_factor;
02317         int shrunken_nz = 1;
02318         int shrunken_nxy = shrunken_nx * shrunken_ny;
02319 
02320         int normalize_shrink_factor = shrink_factor * shrink_factor;
02321         int z_shrink_factor = 1;
02322 
02323         if (nz > 1) {
02324                 shrunken_nz = nz / shrink_factor;
02325                 normalize_shrink_factor *= shrink_factor;
02326                 z_shrink_factor = shrink_factor;
02327         }
02328 
02329         float invnormfactor = 1.0f/(float)normalize_shrink_factor;
02330 
02331         for (int k = 0; k < shrunken_nz; k++) {
02332                 int k_min = k * shrink_factor;
02333                 int k_max = k * shrink_factor + z_shrink_factor;
02334                 size_t cur_k = k * shrunken_nxy;
02335 
02336                 for (int j = 0; j < shrunken_ny; j++) {
02337                         int j_min = j * shrink_factor;
02338                         int j_max = j * shrink_factor + shrink_factor;
02339                         size_t cur_j = j * shrunken_nx + cur_k;
02340 
02341                         for (int i = 0; i < shrunken_nx; i++) {
02342                                 int i_min = i * shrink_factor;
02343                                 int i_max = i * shrink_factor + shrink_factor;
02344 
02345                                 float sum = 0;
02346                                 for (int kk = k_min; kk < k_max; kk++) {
02347                                         size_t cur_kk = kk * nxy;
02348 
02349                                         for (int jj = j_min; jj < j_max; jj++) {
02350                                                 size_t cur_jj = jj * nx + cur_kk;
02351                                                 for (int ii = i_min; ii < i_max; ii++) {
02352                                                         sum += data[ii + cur_jj];
02353                                                 }
02354                                         }
02355                                 }
02356                                 rdata[i + cur_j] = sum * invnormfactor;
02357                         }
02358                 }
02359         }
02360         to->scale_pixel((float)shrink_factor);
02361 }

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

02365 {
02366         int nx0 = from->get_xsize(), ny0 = from->get_ysize();   // the original size
02367 
02368         int nx = to->get_xsize(), ny = to->get_ysize();
02369 
02370         float *data = to->get_data();
02371         const float * const data0 = from->get_const_data();
02372 
02373         for (int j = 0; j < ny; j++) {
02374                 int jj = int(j * 1.5);
02375                 float jw0 = 1.0F, jw1 = 0.5F;   // 3x3 -> 2x2, so each new pixel should have 2.25 of the old pixels
02376                 if ( j%2 ) {
02377                         jw0 = 0.5F;
02378                         jw1 = 1.0F;
02379                 }
02380                 for (int i = 0; i < nx; i++) {
02381                         int ii = int(i * 1.5);
02382                         float iw0 = 1.0F, iw1 = 0.5F;
02383                         float w = 0.0F;
02384 
02385                         if ( i%2 ) {
02386                                 iw0 = 0.5F;
02387                                 iw1 = 1.0F;
02388                         }
02389                         if ( jj < ny0 ) {
02390                                 if ( ii < nx0 ) {
02391                                         data[j * nx + i] = data0[ jj * nx0 + ii ] * jw0 * iw0 ;
02392                                         w += jw0 * iw0 ;
02393                                         if ( ii+1 < nx0 ) {
02394                                                 data[j * nx + i] += data0[ jj * nx0 + ii + 1] * jw0 * iw1;
02395                                                 w += jw0 * iw1;
02396                                         }
02397                                 }
02398                                 if ( jj +1 < ny0 ) {
02399                                         if ( ii < nx0 ) {
02400                                                 data[j * nx + i] += data0[ (jj+1) * nx0 + ii ] * jw1 * iw0;
02401                                                 w += jw1 * iw0;
02402                                                 if ( ii+1 < nx0 ) {
02403                                                         data[j * nx + i] += data0[ (jj+1) * nx0 + ii + 1] * jw1 * iw1;
02404                                                         w += jw1 * iw1;
02405                                                 }
02406                                         }
02407                                 }
02408                         }
02409                         if ( w>0 ) data[j * nx + i] /= w;
02410                 }
02411         }
02412 
02413         to->update();
02414         to->scale_pixel((float)1.5);
02415 }

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

03467                         {
03468                                 return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
03469                         }

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

References NAME.

03472                         {
03473                                 return NAME;
03474                         }

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

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

03481                         {
03482                                 TypeDict d;
03483                                 d.put("n", EMObject::FLOAT, "The shrink factor");
03484                                 return d;
03485                         }

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

Definition at line 3475 of file processor.h.

03476                         {
03477                                 return new MeanShrinkProcessor();
03478                         }

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

02200 {
02201         if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02202 
02203         if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02204 
02205         float shrink_factor0 = params.set_default("n",0.0f);
02206         int shrink_factor = int(shrink_factor0);
02207         if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02208                 throw InvalidValueException(shrink_factor0,
02209                                                                         "mean shrink: shrink factor must be >1 integer or 1.5");
02210         }
02211 
02212         int nx = image->get_xsize();
02213         int ny = image->get_ysize();
02214         int nz = image->get_zsize();
02215 
02216 
02217         // here handle the special averaging by 1.5 for 2D case
02218         if (shrink_factor0==1.5 ) {
02219                 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02220 
02221                 int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
02222                 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02223                 EMData* result = new EMData(shrunken_nx,shrunken_ny,1);
02224 
02225                 accrue_mean_one_p_five(result,image);
02226                 result->update();
02227 
02228                 return result;
02229         }
02230 
02231         int shrunken_nx = nx / shrink_factor;
02232         int shrunken_ny = ny / shrink_factor;
02233         int shrunken_nz = 1;
02234 
02235         if (nz > 1) {
02236                 shrunken_nz = nz / shrink_factor;
02237         }
02238 
02239 //      EMData* result = new EMData(shrunken_nx,shrunken_ny,shrunken_nz);
02240         EMData* result = image->copy_head();
02241         result->set_size(shrunken_nx,shrunken_ny,shrunken_nz);
02242         accrue_mean(result,image,shrink_factor);
02243 
02244         result->update();
02245 
02246         return result;
02247 }

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

02250 {
02251         if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");
02252 
02253         if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }
02254 
02255         float shrink_factor0 = params.set_default("n",0.0f);
02256         int shrink_factor = int(shrink_factor0);
02257         if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
02258                 throw InvalidValueException(shrink_factor0,
02259                                                                         "mean shrink: shrink factor must be >1 integer or 1.5");
02260         }
02261 
02262 /*      if ((nx % shrink_factor != 0) || (ny % shrink_factor != 0) ||
02263         (nz > 1 && (nz % shrink_factor != 0))) {
02264         throw InvalidValueException(shrink_factor,
02265         "Image size not divisible by shrink factor");
02266 }*/
02267 
02268         int nx = image->get_xsize();
02269         int ny = image->get_ysize();
02270         int nz = image->get_zsize();
02271         // here handle the special averaging by 1.5 for 2D case
02272         if (shrink_factor0==1.5 ) {
02273                 if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");
02274 
02275                 int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
02276                 int shrunken_ny = (int(ny / 1.5)+1)/2*2;
02277 
02278                 EMData* orig = image->copy();
02279                 image->set_size(shrunken_nx, shrunken_ny, 1);   // now nx = shrunken_nx, ny = shrunken_ny
02280                 image->to_zero();
02281 
02282                 accrue_mean_one_p_five(image,orig);
02283 
02284                 if( orig ) {
02285                         delete orig;
02286                         orig = 0;
02287                 }
02288                 image->update();
02289 
02290                 return;
02291         }
02292 
02293         accrue_mean(image,image,shrink_factor);
02294 
02295         int shrunken_nx = nx / shrink_factor;
02296         int shrunken_ny = ny / shrink_factor;
02297         int shrunken_nz = 1;
02298         if (nz > 1) shrunken_nz = nz / shrink_factor;
02299 
02300         image->update();
02301         image->set_size(shrunken_nx, shrunken_ny, shrunken_nz);
02302 }


Member Data Documentation

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

Definition at line 3487 of file processor.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Mon Jul 19 13:06:53 2010 for EMAN2 by  doxygen 1.4.4