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

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

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

References NAME.

04038                 {
04039                         return NAME;
04040                 }

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

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

04053                 {
04054                         TypeDict d;
04055                         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.");
04056                         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.");
04057                         d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
04058                         d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
04059                         return d;
04060                 }

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

Definition at line 4047 of file processor.h.

04048                 {
04049                         return new BilateralProcessor();
04050                 }

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

03949 {
03950         if (!image) {
03951                 LOGWARN("NULL Image");
03952                 return;
03953         }
03954 
03955         float distance_sigma = params["distance_sigma"];
03956         float value_sigma = params["value_sigma"];
03957         int max_iter = params["niter"];
03958         int half_width = params["half_width"];
03959 
03960         if (half_width < distance_sigma) {
03961                 LOGWARN("localwidth(=%d) should be larger than distance_sigma=(%f)\n",
03962                                                         half_width, distance_sigma);
03963         }
03964 
03965         distance_sigma *= distance_sigma;
03966 
03967         float image_sigma = image->get_attr("sigma");
03968         if (image_sigma > value_sigma) {
03969                 LOGWARN("image sigma(=%f) should be smaller than value_sigma=(%f)\n",
03970                                                         image_sigma, value_sigma);
03971         }
03972         value_sigma *= value_sigma;
03973 
03974         int nx = image->get_xsize();
03975         int ny = image->get_ysize();
03976         int nz = image->get_zsize();
03977 
03978         if(nz==1) {     //for 2D image
03979                 int width=nx, height=ny;
03980 
03981                 int i,j,m,n;
03982 
03983                 float tempfloat1,tempfloat2,tempfloat3;
03984                 int   index1,index2,index;
03985                 int   Iter;
03986                 int   tempint1,tempint3;
03987 
03988                 tempint1=width;
03989                 tempint3=width+2*half_width;
03990 
03991                 float* mask=(float*)calloc((2*half_width+1)*(2*half_width+1),sizeof(float));
03992                 float* OrgImg=(float*)calloc((2*half_width+width)*(2*half_width+height),sizeof(float));
03993                 float* NewImg=image->get_data();
03994 
03995                 for(m=-(half_width);m<=half_width;m++)
03996                         for(n=-(half_width);n<=half_width;n++) {
03997                    index=(m+half_width)*(2*half_width+1)+(n+half_width);
03998                    mask[index]=exp((float)(-(m*m+n*n)/distance_sigma/2.0));
03999                 }
04000 
04001                 //printf("entering bilateral filtering process \n");
04002 
04003                 Iter=0;
04004                 while(Iter<max_iter) {
04005                         for(i=0;i<height;i++)
04006                         for(j=0;j<width;j++) {
04007                                 index1=(i+half_width)*tempint3+(j+half_width);
04008                                         index2=i*tempint1+j;
04009                                 OrgImg[index1]=NewImg[index2];
04010                         }
04011 
04012                         // Mirror Padding
04013                         for(i=0;i<height;i++){
04014                                 for(j=0;j<half_width;j++) OrgImg[(i+half_width)*tempint3+(j)]=OrgImg[(i+half_width)*tempint3+(2*half_width-j)];
04015                                 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)];
04016                         }
04017                         for(i=0;i<half_width;i++){
04018                                 for(j=0;j<(width+2*half_width);j++) OrgImg[i*tempint3+j]=OrgImg[(2*half_width-i)*tempint3+j];
04019                                 for(j=0;j<(width+2*half_width);j++) OrgImg[(i+height+half_width)*tempint3+j]=OrgImg[(height+half_width-2-i)*tempint3+j];
04020                         }
04021 
04022                         //printf("finish mirror padding process \n");
04023                         //now mirror padding have been done
04024 
04025                         for(i=0;i<height;i++){
04026                                 //printf("now processing the %d th row \n",i);
04027                                 for(j=0;j<width;j++){
04028                                         tempfloat1=0.0; tempfloat2=0.0;
04029                                         for(m=-(half_width);m<=half_width;m++)
04030                                                 for(n=-(half_width);n<=half_width;n++){
04031                                                         index =(m+half_width)*(2*half_width+1)+(n+half_width);
04032                                                         index1=(i+half_width)*tempint3+(j+half_width);
04033                                                         index2=(i+half_width+m)*tempint3+(j+half_width+n);
04034                                                         tempfloat3=(OrgImg[index1]-OrgImg[index2])*(OrgImg[index1]-OrgImg[index2]);
04035 
04036                                                         tempfloat3=mask[index]*(1.0f/(1+tempfloat3/value_sigma));       // Lorentz kernel
04037                                                         //tempfloat3=mask[index]*exp(tempfloat3/Sigma2/(-2.0)); // Guassian kernel
04038                                                         tempfloat1+=tempfloat3;
04039 
04040                                                         tempfloat2+=tempfloat3*OrgImg[(i+half_width+m)*tempint3+(j+half_width+n)];
04041                                         }
04042                                         NewImg[i*width+j]=tempfloat2/tempfloat1;
04043                                 }
04044                         }
04045                         Iter++;
04046             }
04047 
04048             //printf("have finished %d  th iteration\n ",Iter);
04049 //              doneData();
04050                 free(mask);
04051                 free(OrgImg);
04052                 // end of BilaFilter routine
04053 
04054         }
04055         else {  //3D case
04056                 int width = nx;
04057                 int height = ny;
04058                 int slicenum = nz;
04059 
04060                 int slice_size = width * height;
04061                 int new_width = width + 2 * half_width;
04062                 int new_slice_size = (width + 2 * half_width) * (height + 2 * half_width);
04063 
04064                 int width1 = 2 * half_width + 1;
04065                 int mask_size = width1 * width1;
04066                 int old_img_size = (2 * half_width + width) * (2 * half_width + height);
04067 
04068                 int zstart = -half_width;
04069                 int zend = -half_width;
04070                 int is_3d = 0;
04071                 if (nz > 1) {
04072                         mask_size *= width1;
04073                         old_img_size *= (2 * half_width + slicenum);
04074                         zend = half_width;
04075                         is_3d = 1;
04076                 }
04077 
04078                 float *mask = (float *) calloc(mask_size, sizeof(float));
04079                 float *old_img = (float *) calloc(old_img_size, sizeof(float));
04080 
04081                 float *new_img = image->get_data();
04082 
04083                 for (int p = zstart; p <= zend; p++) {
04084                         int cur_p = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
04085 
04086                         for (int m = -half_width; m <= half_width; m++) {
04087                                 int cur_m = (m + half_width) * (2 * half_width + 1) + half_width;
04088 
04089                                 for (int n = -half_width; n <= half_width; n++) {
04090                                         int l = cur_p + cur_m + n;
04091                                         mask[l] = exp((float) (-(m * m + n * n + p * p * is_3d) / distance_sigma / 2.0f));
04092                                 }
04093                         }
04094                 }
04095 
04096                 int iter = 0;
04097                 while (iter < max_iter) {
04098                         for (int k = 0; k < slicenum; k++) {
04099                                 int cur_k1 = (k + half_width) * new_slice_size * is_3d;
04100                                 int cur_k2 = k * slice_size;
04101 
04102                                 for (int i = 0; i < height; i++) {
04103                                         int cur_i1 = (i + half_width) * new_width;
04104                                         int cur_i2 = i * width;
04105 
04106                                         for (int j = 0; j < width; j++) {
04107                                                 int k1 = cur_k1 + cur_i1 + (j + half_width);
04108                                                 int k2 = cur_k2 + cur_i2 + j;
04109                                                 old_img[k1] = new_img[k2];
04110                                         }
04111                                 }
04112                         }
04113 
04114                         for (int k = 0; k < slicenum; k++) {
04115                                 int cur_k = (k + half_width) * new_slice_size * is_3d;
04116 
04117                                 for (int i = 0; i < height; i++) {
04118                                         int cur_i = (i + half_width) * new_width;
04119 
04120                                         for (int j = 0; j < half_width; j++) {
04121                                                 int k1 = cur_k + cur_i + j;
04122                                                 int k2 = cur_k + cur_i + (2 * half_width - j);
04123                                                 old_img[k1] = old_img[k2];
04124                                         }
04125 
04126                                         for (int j = 0; j < half_width; j++) {
04127                                                 int k1 = cur_k + cur_i + (width + half_width + j);
04128                                                 int k2 = cur_k + cur_i + (width + half_width - j - 2);
04129                                                 old_img[k1] = old_img[k2];
04130                                         }
04131                                 }
04132 
04133 
04134                                 for (int i = 0; i < half_width; i++) {
04135                                         int i2 = i * new_width;
04136                                         int i3 = (2 * half_width - i) * new_width;
04137                                         for (int j = 0; j < (width + 2 * half_width); j++) {
04138                                                 int k1 = cur_k + i2 + j;
04139                                                 int k2 = cur_k + i3 + j;
04140                                                 old_img[k1] = old_img[k2];
04141                                         }
04142 
04143                                         i2 = (height + half_width + i) * new_width;
04144                                         i3 = (height + half_width - 2 - i) * new_width;
04145                                         for (int j = 0; j < (width + 2 * half_width); j++) {
04146                                                 int k1 = cur_k + i2 + j;
04147                                                 int k2 = cur_k + i3 + j;
04148                                                 old_img[k1] = old_img[k2];
04149                                         }
04150                                 }
04151                         }
04152 
04153                         size_t idx;
04154                         for (int k = 0; k < slicenum; k++) {
04155                                 int cur_k = (k + half_width) * new_slice_size;
04156 
04157                                 for (int i = 0; i < height; i++) {
04158                                         int cur_i = (i + half_width) * new_width;
04159 
04160                                         for (int j = 0; j < width; j++) {
04161                                                 float f1 = 0;
04162                                                 float f2 = 0;
04163                                                 int k1 = cur_k + cur_i + (j + half_width);
04164 
04165                                                 for (int p = zstart; p <= zend; p++) {
04166                                                         int cur_p1 = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
04167                                                         int cur_p2 = (k + half_width + p) * new_slice_size;
04168 
04169                                                         for (int m = -half_width; m <= half_width; m++) {
04170                                                                 int cur_m1 = (m + half_width) * (2 * half_width + 1);
04171                                                                 int cur_m2 = cur_p2 + cur_i + m * new_width + j + half_width;
04172 
04173                                                                 for (int n = -half_width; n <= half_width; n++) {
04174                                                                         int k = cur_p1 + cur_m1 + (n + half_width);
04175                                                                         int k2 = cur_m2 + n;
04176                                                                         float f3 = Util::square(old_img[k1] - old_img[k2]);
04177 
04178                                                                         f3 = mask[k] * (1.0f / (1 + f3 / value_sigma));
04179                                                                         f1 += f3;
04180                                                                         int l1 = cur_m2 + n;
04181                                                                         f2 += f3 * old_img[l1];
04182                                                                 }
04183 
04184                                                                 idx = k * height * width + i * width + j;
04185                                                                 new_img[idx] = f2 / f1;
04186                                                         }
04187                                                 }
04188                                         }
04189                                 }
04190                         }
04191                         iter++;
04192                 }
04193                 if( mask ) {
04194                         free(mask);
04195                         mask = 0;
04196                 }
04197 
04198                 if( old_img ) {
04199                         free(old_img);
04200                         old_img = 0;
04201                 }
04202         }
04203 
04204         image->update();
04205 }


Member Data Documentation

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

Definition at line 4062 of file processor.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Mon Jul 19 12:43:39 2010 for EMAN2 by  doxygen 1.4.7