Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

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

ProcessorNEW ()

Static Public Attributes

const string NAME = "filter.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 4074 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 4083 of file processor.h.

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

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

04079                 {
04080                         return NAME;
04081                 }

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

References EMAN::TypeDict::put().

04094                 {
04095                         TypeDict d;
04096                         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.");
04097                         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.");
04098                         d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
04099                         d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
04100                         return d;
04101                 }

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

Definition at line 4088 of file processor.h.

04089                 {
04090                         return new BilateralProcessor();
04091                 }

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 3988 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, nx, ny, square, and EMAN::EMData::update().

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


Member Data Documentation

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

Definition at line 142 of file processor.cpp.


The documentation for this class was generated from the following files:
Generated on Tue Jun 11 13:42:32 2013 for EMAN2 by  doxygen 1.3.9.1