EMAN::BilateralProcessor Class Reference

Bilateral processing on 2D or 3D volume data. More...

#include <processor.h>

Inheritance diagram for EMAN::BilateralProcessor:

Inheritance graph
[legend]
Collaboration diagram for EMAN::BilateralProcessor:

Collaboration graph
[legend]
List of all members.

Public Member Functions

void process_inplace (EMData *image)
 To process an image in-place.
string get_name () const
 Get the processor's name.
string get_desc () const
 Get the descrition of this specific processor.
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 = "bilateral"

Detailed Description

Bilateral processing on 2D or 3D volume data.

Bilateral processing does non-linear weighted averaging processing within a certain window.

Parameters:
distance_sigma means how large the voxel has impact on its neighbors in spatial domain. The larger it is, the more blurry the resulting image.
value_sigma eans how large the voxel has impact on its in range domain. The larger it is, the more blurry the resulting image.
niter how many times to apply this processing on your data.
half_width processing window size = (2 * half_widthh + 1) ^ 3.

Definition at line 3958 of file processor.h.


Member Function Documentation

string EMAN::BilateralProcessor::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 3967 of file processor.h.

03968                 {
03969                         return "Bilateral processing on 2D or 3D volume data. Bilateral processing does non-linear weighted averaging processing within a certain window. ";
03970                 }

string EMAN::BilateralProcessor::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 3962 of file processor.h.

References NAME.

03963                 {
03964                         return NAME;
03965                 }

TypeDict EMAN::BilateralProcessor::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 3977 of file processor.h.

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

03978                 {
03979                         TypeDict d;
03980                         d.put("distance_sigma", EMObject::FLOAT, "means how large the voxel has impact on its neighbors in spatial domain. The larger it is, the more blurry the resulting image.");
03981                         d.put("value_sigma", EMObject::FLOAT, "means how large the voxel has impact on its in  range domain. The larger it is, the more blurry the resulting image.");
03982                         d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
03983                         d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
03984                         return d;
03985                 }

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

Definition at line 3972 of file processor.h.

03973                 {
03974                         return new BilateralProcessor();
03975                 }

void BilateralProcessor::process_inplace ( EMData image  )  [virtual]

To process an image in-place.

For those processors which can only be processed out-of-place, override this function to just print out some error message to remind user call the out-of-place version.

Parameters:
image The image to be processed.

Implements EMAN::Processor.

Definition at line 3867 of file processor.cpp.

References EMAN::EMData::get_attr(), EMAN::EMData::get_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), LOGWARN, EMAN::Processor::params, square, and EMAN::EMData::update().

03868 {
03869         if (!image) {
03870                 LOGWARN("NULL Image");
03871                 return;
03872         }
03873 
03874         float distance_sigma = params["distance_sigma"];
03875         float value_sigma = params["value_sigma"];
03876         int max_iter = params["niter"];
03877         int half_width = params["half_width"];
03878 
03879         if (half_width < distance_sigma) {
03880                 LOGWARN("localwidth(=%d) should be larger than distance_sigma=(%f)\n",
03881                                                         half_width, distance_sigma);
03882         }
03883 
03884         distance_sigma *= distance_sigma;
03885 
03886         float image_sigma = image->get_attr("sigma");
03887         if (image_sigma > value_sigma) {
03888                 LOGWARN("image sigma(=%f) should be smaller than value_sigma=(%f)\n",
03889                                                         image_sigma, value_sigma);
03890         }
03891         value_sigma *= value_sigma;
03892 
03893         int nx = image->get_xsize();
03894         int ny = image->get_ysize();
03895         int nz = image->get_zsize();
03896 
03897         if(nz==1) {     //for 2D image
03898                 int width=nx, height=ny;
03899 
03900                 int i,j,m,n;
03901 
03902                 float tempfloat1,tempfloat2,tempfloat3;
03903                 int   index1,index2,index;
03904                 int   Iter;
03905                 int   tempint1,tempint3;
03906 
03907                 tempint1=width;
03908                 tempint3=width+2*half_width;
03909 
03910                 float* mask=(float*)calloc((2*half_width+1)*(2*half_width+1),sizeof(float));
03911                 float* OrgImg=(float*)calloc((2*half_width+width)*(2*half_width+height),sizeof(float));
03912                 float* NewImg=image->get_data();
03913 
03914                 for(m=-(half_width);m<=half_width;m++)
03915                         for(n=-(half_width);n<=half_width;n++) {
03916                    index=(m+half_width)*(2*half_width+1)+(n+half_width);
03917                    mask[index]=exp((float)(-(m*m+n*n)/distance_sigma/2.0));
03918                 }
03919 
03920                 //printf("entering bilateral filtering process \n");
03921 
03922                 Iter=0;
03923                 while(Iter<max_iter) {
03924                         for(i=0;i<height;i++)
03925                         for(j=0;j<width;j++) {
03926                                 index1=(i+half_width)*tempint3+(j+half_width);
03927                                         index2=i*tempint1+j;
03928                                 OrgImg[index1]=NewImg[index2];
03929                         }
03930 
03931                         // Mirror Padding
03932                         for(i=0;i<height;i++){
03933                                 for(j=0;j<half_width;j++) OrgImg[(i+half_width)*tempint3+(j)]=OrgImg[(i+half_width)*tempint3+(2*half_width-j)];
03934                                 for(j=0;j<half_width;j++) OrgImg[(i+half_width)*tempint3+(j+width+half_width)]=OrgImg[(i+half_width)*tempint3+(width+half_width-j-2)];
03935                         }
03936                         for(i=0;i<half_width;i++){
03937                                 for(j=0;j<(width+2*half_width);j++) OrgImg[i*tempint3+j]=OrgImg[(2*half_width-i)*tempint3+j];
03938                                 for(j=0;j<(width+2*half_width);j++) OrgImg[(i+height+half_width)*tempint3+j]=OrgImg[(height+half_width-2-i)*tempint3+j];
03939                         }
03940 
03941                         //printf("finish mirror padding process \n");
03942                         //now mirror padding have been done
03943 
03944                         for(i=0;i<height;i++){
03945                                 //printf("now processing the %d th row \n",i);
03946                                 for(j=0;j<width;j++){
03947                                         tempfloat1=0.0; tempfloat2=0.0;
03948                                         for(m=-(half_width);m<=half_width;m++)
03949                                                 for(n=-(half_width);n<=half_width;n++){
03950                                                         index =(m+half_width)*(2*half_width+1)+(n+half_width);
03951                                                         index1=(i+half_width)*tempint3+(j+half_width);
03952                                                         index2=(i+half_width+m)*tempint3+(j+half_width+n);
03953                                                         tempfloat3=(OrgImg[index1]-OrgImg[index2])*(OrgImg[index1]-OrgImg[index2]);
03954 
03955                                                         tempfloat3=mask[index]*(1.0f/(1+tempfloat3/value_sigma));       // Lorentz kernel
03956                                                         //tempfloat3=mask[index]*exp(tempfloat3/Sigma2/(-2.0)); // Guassian kernel
03957                                                         tempfloat1+=tempfloat3;
03958 
03959                                                         tempfloat2+=tempfloat3*OrgImg[(i+half_width+m)*tempint3+(j+half_width+n)];
03960                                         }
03961                                         NewImg[i*width+j]=tempfloat2/tempfloat1;
03962                                 }
03963                         }
03964                         Iter++;
03965             }
03966 
03967             //printf("have finished %d  th iteration\n ",Iter);
03968 //              doneData();
03969                 free(mask);
03970                 free(OrgImg);
03971                 // end of BilaFilter routine
03972 
03973         }
03974         else {  //3D case
03975                 int width = nx;
03976                 int height = ny;
03977                 int slicenum = nz;
03978 
03979                 int slice_size = width * height;
03980                 int new_width = width + 2 * half_width;
03981                 int new_slice_size = (width + 2 * half_width) * (height + 2 * half_width);
03982 
03983                 int width1 = 2 * half_width + 1;
03984                 int mask_size = width1 * width1;
03985                 int old_img_size = (2 * half_width + width) * (2 * half_width + height);
03986 
03987                 int zstart = -half_width;
03988                 int zend = -half_width;
03989                 int is_3d = 0;
03990                 if (nz > 1) {
03991                         mask_size *= width1;
03992                         old_img_size *= (2 * half_width + slicenum);
03993                         zend = half_width;
03994                         is_3d = 1;
03995                 }
03996 
03997                 float *mask = (float *) calloc(mask_size, sizeof(float));
03998                 float *old_img = (float *) calloc(old_img_size, sizeof(float));
03999 
04000                 float *new_img = image->get_data();
04001 
04002                 for (int p = zstart; p <= zend; p++) {
04003                         int cur_p = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
04004 
04005                         for (int m = -half_width; m <= half_width; m++) {
04006                                 int cur_m = (m + half_width) * (2 * half_width + 1) + half_width;
04007 
04008                                 for (int n = -half_width; n <= half_width; n++) {
04009                                         int l = cur_p + cur_m + n;
04010                                         mask[l] = exp((float) (-(m * m + n * n + p * p * is_3d) / distance_sigma / 2.0f));
04011                                 }
04012                         }
04013                 }
04014 
04015                 int iter = 0;
04016                 while (iter < max_iter) {
04017                         for (int k = 0; k < slicenum; k++) {
04018                                 size_t cur_k1 = (size_t)(k + half_width) * new_slice_size * is_3d;
04019                                 int cur_k2 = k * slice_size;
04020 
04021                                 for (int i = 0; i < height; i++) {
04022                                         int cur_i1 = (i + half_width) * new_width;
04023                                         int cur_i2 = i * width;
04024 
04025                                         for (int j = 0; j < width; j++) {
04026                                                 size_t k1 = cur_k1 + cur_i1 + (j + half_width);
04027                                                 int k2 = cur_k2 + cur_i2 + j;
04028                                                 old_img[k1] = new_img[k2];
04029                                         }
04030                                 }
04031                         }
04032 
04033                         for (int k = 0; k < slicenum; k++) {
04034                                 size_t cur_k = (k + half_width) * new_slice_size * is_3d;
04035 
04036                                 for (int i = 0; i < height; i++) {
04037                                         int cur_i = (i + half_width) * new_width;
04038 
04039                                         for (int j = 0; j < half_width; j++) {
04040                                                 size_t k1 = cur_k + cur_i + j;
04041                                                 size_t k2 = cur_k + cur_i + (2 * half_width - j);
04042                                                 old_img[k1] = old_img[k2];
04043                                         }
04044 
04045                                         for (int j = 0; j < half_width; j++) {
04046                                                 size_t k1 = cur_k + cur_i + (width + half_width + j);
04047                                                 size_t k2 = cur_k + cur_i + (width + half_width - j - 2);
04048                                                 old_img[k1] = old_img[k2];
04049                                         }
04050                                 }
04051 
04052 
04053                                 for (int i = 0; i < half_width; i++) {
04054                                         int i2 = i * new_width;
04055                                         int i3 = (2 * half_width - i) * new_width;
04056                                         for (int j = 0; j < (width + 2 * half_width); j++) {
04057                                                 size_t k1 = cur_k + i2 + j;
04058                                                 size_t k2 = cur_k + i3 + j;
04059                                                 old_img[k1] = old_img[k2];
04060                                         }
04061 
04062                                         i2 = (height + half_width + i) * new_width;
04063                                         i3 = (height + half_width - 2 - i) * new_width;
04064                                         for (int j = 0; j < (width + 2 * half_width); j++) {
04065                                                 size_t k1 = cur_k + i2 + j;
04066                                                 size_t k2 = cur_k + i3 + j;
04067                                                 old_img[k1] = old_img[k2];
04068                                         }
04069                                 }
04070                         }
04071 
04072                         size_t idx;
04073                         for (int k = 0; k < slicenum; k++) {
04074                                 size_t cur_k = (k + half_width) * new_slice_size;
04075 
04076                                 for (int i = 0; i < height; i++) {
04077                                         int cur_i = (i + half_width) * new_width;
04078 
04079                                         for (int j = 0; j < width; j++) {
04080                                                 float f1 = 0;
04081                                                 float f2 = 0;
04082                                                 size_t k1 = cur_k + cur_i + (j + half_width);
04083 
04084                                                 for (int p = zstart; p <= zend; p++) {
04085                                                         size_t cur_p1 = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
04086                                                         size_t cur_p2 = (k + half_width + p) * new_slice_size;
04087 
04088                                                         for (int m = -half_width; m <= half_width; m++) {
04089                                                                 size_t cur_m1 = (m + half_width) * (2 * half_width + 1);
04090                                                                 size_t cur_m2 = cur_p2 + cur_i + m * new_width + j + half_width;
04091 
04092                                                                 for (int n = -half_width; n <= half_width; n++) {
04093                                                                         size_t k = cur_p1 + cur_m1 + (n + half_width);
04094                                                                         size_t k2 = cur_m2 + n;
04095                                                                         float f3 = Util::square(old_img[k1] - old_img[k2]);
04096 
04097                                                                         f3 = mask[k] * (1.0f / (1 + f3 / value_sigma));
04098                                                                         f1 += f3;
04099                                                                         size_t l1 = cur_m2 + n;
04100                                                                         f2 += f3 * old_img[l1];
04101                                                                 }
04102 
04103                                                                 idx = (size_t)k * height * width + i * width + j;
04104                                                                 new_img[idx] = f2 / f1;
04105                                                         }
04106                                                 }
04107                                         }
04108                                 }
04109                         }
04110                         iter++;
04111                 }
04112                 if( mask ) {
04113                         free(mask);
04114                         mask = 0;
04115                 }
04116 
04117                 if( old_img ) {
04118                         free(old_img);
04119                         old_img = 0;
04120                 }
04121         }
04122 
04123         image->update();
04124 }


Member Data Documentation

const string BilateralProcessor::NAME = "bilateral" [static]

Definition at line 3987 of file processor.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Mon May 2 13:30:34 2011 for EMAN2 by  doxygen 1.4.7