EMAN2
Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Member Functions
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:
nThe shrink factor

Definition at line 3636 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:
tothe smaller image that will store the mean values
fromthe larger image that will be used to calculate the mean values
shrinkfactorthe shrink amount

Definition at line 2299 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(), ny, rdata, and EMAN::EMData::scale_pixel().

{
        const float * const data = from->get_const_data();
        float* rdata = to->get_data();

        size_t nx = from->get_xsize();
        size_t ny = from->get_ysize();
        size_t nz = from->get_zsize();
        size_t nxy = nx*ny;


        size_t shrunken_nx = nx / shrink_factor;
        size_t shrunken_ny = ny / shrink_factor;
        size_t shrunken_nz = 1;
        size_t shrunken_nxy = shrunken_nx * shrunken_ny;

        int normalize_shrink_factor = shrink_factor * shrink_factor;
        int z_shrink_factor = 1;

        if (nz > 1) {
                shrunken_nz = nz / shrink_factor;
                normalize_shrink_factor *= shrink_factor;
                z_shrink_factor = shrink_factor;
        }

        float invnormfactor = 1.0f/(float)normalize_shrink_factor;

        for (size_t k = 0; k < shrunken_nz; k++) {
                size_t k_min = k * shrink_factor;
                size_t k_max = k * shrink_factor + z_shrink_factor;
                size_t cur_k = k * shrunken_nxy;

                for (size_t j = 0; j < shrunken_ny; j++) {
                        size_t j_min = j * shrink_factor;
                        size_t j_max = j * shrink_factor + shrink_factor;
                        size_t cur_j = j * shrunken_nx + cur_k;

                        for (size_t i = 0; i < shrunken_nx; i++) {
                                size_t i_min = i * shrink_factor;
                                size_t i_max = i * shrink_factor + shrink_factor;

                                float sum = 0;
                                for (size_t kk = k_min; kk < k_max; kk++) {
                                        size_t cur_kk = kk * nxy;

                                        for (size_t jj = j_min; jj < j_max; jj++) {
                                                size_t cur_jj = jj * nx + cur_kk;
                                                for (size_t ii = i_min; ii < i_max; ii++) {
                                                        sum += data[ii + cur_jj];
                                                }
                                        }
                                }
                                rdata[i + cur_j] = sum * invnormfactor;
                        }
                }
        }
        to->scale_pixel((float)shrink_factor);
}
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:
tothe smaller image that will store the mean values
fromthe larger image that will be used to calculate the mean values

Definition at line 2359 of file processor.cpp.

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

{
        int nx0 = from->get_xsize(), ny0 = from->get_ysize();   // the original size

        int nx = to->get_xsize(), ny = to->get_ysize();

        float *data = to->get_data();
        const float * const data0 = from->get_const_data();

        for (int j = 0; j < ny; j++) {
                int jj = int(j * 1.5);
                float jw0 = 1.0F, jw1 = 0.5F;   // 3x3 -> 2x2, so each new pixel should have 2.25 of the old pixels
                if ( j%2 ) {
                        jw0 = 0.5F;
                        jw1 = 1.0F;
                }
                for (int i = 0; i < nx; i++) {
                        int ii = int(i * 1.5);
                        float iw0 = 1.0F, iw1 = 0.5F;
                        float w = 0.0F;

                        if ( i%2 ) {
                                iw0 = 0.5F;
                                iw1 = 1.0F;
                        }
                        if ( jj < ny0 ) {
                                if ( ii < nx0 ) {
                                        data[j * nx + i] = data0[ jj * nx0 + ii ] * jw0 * iw0 ;
                                        w += jw0 * iw0 ;
                                        if ( ii+1 < nx0 ) {
                                                data[j * nx + i] += data0[ jj * nx0 + ii + 1] * jw0 * iw1;
                                                w += jw0 * iw1;
                                        }
                                }
                                if ( jj +1 < ny0 ) {
                                        if ( ii < nx0 ) {
                                                data[j * nx + i] += data0[ (jj+1) * nx0 + ii ] * jw1 * iw0;
                                                w += jw1 * iw0;
                                                if ( ii+1 < nx0 ) {
                                                        data[j * nx + i] += data0[ (jj+1) * nx0 + ii + 1] * jw1 * iw1;
                                                        w += jw1 * iw1;
                                                }
                                        }
                                }
                        }
                        if ( w>0 ) data[j * nx + i] /= w;
                }
        }

        to->update();
        to->scale_pixel((float)1.5);
}
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 3659 of file processor.h.

                        {
                                return "Shrink an image by a given amount , using the mean value found in the pixel neighborhood.";
                        }
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 3664 of file processor.h.

References NAME.

                        {
                                return NAME;
                        }
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 3673 of file processor.h.

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

                        {
                                TypeDict d;
                                d.put("n", EMObject::FLOAT, "The shrink factor");
                                return d;
                        }
static Processor* EMAN::MeanShrinkProcessor::NEW ( ) [inline, static]

Definition at line 3668 of file processor.h.

                        {
                                return new MeanShrinkProcessor();
                        }
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:
imagethe image that will be used to generate a 'mean shrunken' image
Exceptions:
ImageFormatExceptionif the image is complex
ImageDimensionExceptionif the image is 1D
InvalidValueExceptionif the shrink amount is a nonzero integer, unless it is 1.5, which is an exceptional circumstance

Reimplemented from EMAN::Processor.

Definition at line 2194 of file processor.cpp.

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

{
        if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");

        if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }

        float shrink_factor0 = params.set_default("n",0.0f);
        int shrink_factor = int(shrink_factor0);
        if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
                throw InvalidValueException(shrink_factor0,
                                                                        "mean shrink: shrink factor must be >1 integer or 1.5");
        }

        int nx = image->get_xsize();
        int ny = image->get_ysize();
        int nz = image->get_zsize();


        // here handle the special averaging by 1.5 for 2D case
        if (shrink_factor0==1.5 ) {
                if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");

                int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
                int shrunken_ny = (int(ny / 1.5)+1)/2*2;
                EMData* result = new EMData(shrunken_nx,shrunken_ny,1);

                accrue_mean_one_p_five(result,image);
                result->update();

                return result;
        }

        int shrunken_nx = nx / shrink_factor;
        int shrunken_ny = ny / shrink_factor;
        int shrunken_nz = 1;

        if (nz > 1) {
                shrunken_nz = nz / shrink_factor;
        }

//      EMData* result = new EMData(shrunken_nx,shrunken_ny,shrunken_nz);
        EMData* result = image->copy_head();
        result->set_size(shrunken_nx,shrunken_ny,shrunken_nz);
        accrue_mean(result,image,shrink_factor);

        result->update();

        return result;
}
void MeanShrinkProcessor::process_inplace ( EMData image) [virtual]

Mean shrink inplace.

Parameters:
imagethe image that will be 'mean shrunken' inplace
Exceptions:
ImageFormatExceptionif the image is complex
ImageDimensionExceptionif the image is 1D
InvalidValueExceptionif the shrink amount is a nonzero integer, unless it is 1.5, which is an exceptional circumstance

Implements EMAN::Processor.

Definition at line 2244 of file processor.cpp.

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

{
        if (image->is_complex()) throw ImageFormatException("Error, the mean shrink processor does not work on complex images");

        if (image->get_ndim() == 1) { throw ImageDimensionException("Error, mean shrink works only for 2D & 3D images"); }

        float shrink_factor0 = params.set_default("n",0.0f);
        int shrink_factor = int(shrink_factor0);
        if (shrink_factor0 <= 1.0F || ((shrink_factor0 != shrink_factor) && (shrink_factor0 != 1.5F) ) ) {
                throw InvalidValueException(shrink_factor0,
                                                                        "mean shrink: shrink factor must be >1 integer or 1.5");
        }

/*      if ((nx % shrink_factor != 0) || (ny % shrink_factor != 0) ||
        (nz > 1 && (nz % shrink_factor != 0))) {
        throw InvalidValueException(shrink_factor,
        "Image size not divisible by shrink factor");
}*/

        int nx = image->get_xsize();
        int ny = image->get_ysize();
        int nz = image->get_zsize();
        // here handle the special averaging by 1.5 for 2D case
        if (shrink_factor0==1.5 ) {
                if (nz > 1 ) throw InvalidValueException(shrink_factor0, "mean shrink: only support 2D images for shrink factor = 1.5");

                int shrunken_nx = (int(nx / 1.5)+1)/2*2;        // make sure the output size is even
                int shrunken_ny = (int(ny / 1.5)+1)/2*2;

                EMData* orig = image->copy();
                image->set_size(shrunken_nx, shrunken_ny, 1);   // now nx = shrunken_nx, ny = shrunken_ny
                image->to_zero();

                accrue_mean_one_p_five(image,orig);

                if( orig ) {
                        delete orig;
                        orig = 0;
                }
                image->update();

                return;
        }

        accrue_mean(image,image,shrink_factor);

        int shrunken_nx = nx / shrink_factor;
        int shrunken_ny = ny / shrink_factor;
        int shrunken_nz = 1;
        if (nz > 1) shrunken_nz = nz / shrink_factor;

        image->update();
        image->set_size(shrunken_nx, shrunken_ny, shrunken_nz);
}

Member Data Documentation

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

Definition at line 3680 of file processor.h.

Referenced by get_name().


The documentation for this class was generated from the following files: