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 = "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 3817 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 3826 of file processor.h.

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

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

03822                 {
03823                         return NAME;
03824                 }

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

References EMAN::TypeDict::put().

03837                 {
03838                         TypeDict d;
03839                         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.");
03840                         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.");
03841                         d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
03842                         d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
03843                         return d;
03844                 }

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

Definition at line 3831 of file processor.h.

03832                 {
03833                         return new BilateralProcessor();
03834                 }

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

03810 {
03811         if (!image) {
03812                 LOGWARN("NULL Image");
03813                 return;
03814         }
03815 
03816         float distance_sigma = params["distance_sigma"];
03817         float value_sigma = params["value_sigma"];
03818         int max_iter = params["niter"];
03819         int half_width = params["half_width"];
03820 
03821         if (half_width < distance_sigma) {
03822                 LOGWARN("localwidth(=%d) should be larger than distance_sigma=(%f)\n",
03823                                                         half_width, distance_sigma);
03824         }
03825 
03826         distance_sigma *= distance_sigma;
03827 
03828         float image_sigma = image->get_attr("sigma");
03829         if (image_sigma > value_sigma) {
03830                 LOGWARN("image sigma(=%f) should be smaller than value_sigma=(%f)\n",
03831                                                         image_sigma, value_sigma);
03832         }
03833         value_sigma *= value_sigma;
03834 
03835         int nx = image->get_xsize();
03836         int ny = image->get_ysize();
03837         int nz = image->get_zsize();
03838 
03839         if(nz==1) {     //for 2D image
03840                 int width=nx, height=ny;
03841 
03842                 int i,j,m,n;
03843 
03844                 float tempfloat1,tempfloat2,tempfloat3;
03845                 int   index1,index2,index;
03846                 int   Iter;
03847                 int   tempint1,tempint3;
03848 
03849                 tempint1=width;
03850                 tempint3=width+2*half_width;
03851 
03852                 float* mask=(float*)calloc((2*half_width+1)*(2*half_width+1),sizeof(float));
03853                 float* OrgImg=(float*)calloc((2*half_width+width)*(2*half_width+height),sizeof(float));
03854                 float* NewImg=image->get_data();
03855 
03856                 for(m=-(half_width);m<=half_width;m++)
03857                         for(n=-(half_width);n<=half_width;n++) {
03858                    index=(m+half_width)*(2*half_width+1)+(n+half_width);
03859                    mask[index]=exp((float)(-(m*m+n*n)/distance_sigma/2.0));
03860                 }
03861 
03862                 //printf("entering bilateral filtering process \n");
03863 
03864                 Iter=0;
03865                 while(Iter<max_iter) {
03866                         for(i=0;i<height;i++)
03867                         for(j=0;j<width;j++) {
03868                                 index1=(i+half_width)*tempint3+(j+half_width);
03869                                         index2=i*tempint1+j;
03870                                 OrgImg[index1]=NewImg[index2];
03871                         }
03872 
03873                         // Mirror Padding
03874                         for(i=0;i<height;i++){
03875                                 for(j=0;j<half_width;j++) OrgImg[(i+half_width)*tempint3+(j)]=OrgImg[(i+half_width)*tempint3+(2*half_width-j)];
03876                                 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)];
03877                         }
03878                         for(i=0;i<half_width;i++){
03879                                 for(j=0;j<(width+2*half_width);j++) OrgImg[i*tempint3+j]=OrgImg[(2*half_width-i)*tempint3+j];
03880                                 for(j=0;j<(width+2*half_width);j++) OrgImg[(i+height+half_width)*tempint3+j]=OrgImg[(height+half_width-2-i)*tempint3+j];
03881                         }
03882 
03883                         //printf("finish mirror padding process \n");
03884                         //now mirror padding have been done
03885 
03886                         for(i=0;i<height;i++){
03887                                 //printf("now processing the %d th row \n",i);
03888                                 for(j=0;j<width;j++){
03889                                         tempfloat1=0.0; tempfloat2=0.0;
03890                                         for(m=-(half_width);m<=half_width;m++)
03891                                                 for(n=-(half_width);n<=half_width;n++){
03892                                                         index =(m+half_width)*(2*half_width+1)+(n+half_width);
03893                                                         index1=(i+half_width)*tempint3+(j+half_width);
03894                                                         index2=(i+half_width+m)*tempint3+(j+half_width+n);
03895                                                         tempfloat3=(OrgImg[index1]-OrgImg[index2])*(OrgImg[index1]-OrgImg[index2]);
03896 
03897                                                         tempfloat3=mask[index]*(1.0f/(1+tempfloat3/value_sigma));       // Lorentz kernel
03898                                                         //tempfloat3=mask[index]*exp(tempfloat3/Sigma2/(-2.0)); // Guassian kernel
03899                                                         tempfloat1+=tempfloat3;
03900 
03901                                                         tempfloat2+=tempfloat3*OrgImg[(i+half_width+m)*tempint3+(j+half_width+n)];
03902                                         }
03903                                         NewImg[i*width+j]=tempfloat2/tempfloat1;
03904                                 }
03905                         }
03906                         Iter++;
03907             }
03908 
03909             //printf("have finished %d  th iteration\n ",Iter);
03910 //              doneData();
03911                 free(mask);
03912                 free(OrgImg);
03913                 // end of BilaFilter routine
03914 
03915         }
03916         else {  //3D case
03917                 int width = nx;
03918                 int height = ny;
03919                 int slicenum = nz;
03920 
03921                 int slice_size = width * height;
03922                 int new_width = width + 2 * half_width;
03923                 int new_slice_size = (width + 2 * half_width) * (height + 2 * half_width);
03924 
03925                 int width1 = 2 * half_width + 1;
03926                 int mask_size = width1 * width1;
03927                 int old_img_size = (2 * half_width + width) * (2 * half_width + height);
03928 
03929                 int zstart = -half_width;
03930                 int zend = -half_width;
03931                 int is_3d = 0;
03932                 if (nz > 1) {
03933                         mask_size *= width1;
03934                         old_img_size *= (2 * half_width + slicenum);
03935                         zend = half_width;
03936                         is_3d = 1;
03937                 }
03938 
03939                 float *mask = (float *) calloc(mask_size, sizeof(float));
03940                 float *old_img = (float *) calloc(old_img_size, sizeof(float));
03941 
03942                 float *new_img = image->get_data();
03943 
03944                 for (int p = zstart; p <= zend; p++) {
03945                         int cur_p = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
03946 
03947                         for (int m = -half_width; m <= half_width; m++) {
03948                                 int cur_m = (m + half_width) * (2 * half_width + 1) + half_width;
03949 
03950                                 for (int n = -half_width; n <= half_width; n++) {
03951                                         int l = cur_p + cur_m + n;
03952                                         mask[l] = exp((float) (-(m * m + n * n + p * p * is_3d) / distance_sigma / 2.0f));
03953                                 }
03954                         }
03955                 }
03956 
03957                 int iter = 0;
03958                 while (iter < max_iter) {
03959                         for (int k = 0; k < slicenum; k++) {
03960                                 int cur_k1 = (k + half_width) * new_slice_size * is_3d;
03961                                 int cur_k2 = k * slice_size;
03962 
03963                                 for (int i = 0; i < height; i++) {
03964                                         int cur_i1 = (i + half_width) * new_width;
03965                                         int cur_i2 = i * width;
03966 
03967                                         for (int j = 0; j < width; j++) {
03968                                                 int k1 = cur_k1 + cur_i1 + (j + half_width);
03969                                                 int k2 = cur_k2 + cur_i2 + j;
03970                                                 old_img[k1] = new_img[k2];
03971                                         }
03972                                 }
03973                         }
03974 
03975                         for (int k = 0; k < slicenum; k++) {
03976                                 int cur_k = (k + half_width) * new_slice_size * is_3d;
03977 
03978                                 for (int i = 0; i < height; i++) {
03979                                         int cur_i = (i + half_width) * new_width;
03980 
03981                                         for (int j = 0; j < half_width; j++) {
03982                                                 int k1 = cur_k + cur_i + j;
03983                                                 int k2 = cur_k + cur_i + (2 * half_width - j);
03984                                                 old_img[k1] = old_img[k2];
03985                                         }
03986 
03987                                         for (int j = 0; j < half_width; j++) {
03988                                                 int k1 = cur_k + cur_i + (width + half_width + j);
03989                                                 int k2 = cur_k + cur_i + (width + half_width - j - 2);
03990                                                 old_img[k1] = old_img[k2];
03991                                         }
03992                                 }
03993 
03994 
03995                                 for (int i = 0; i < half_width; i++) {
03996                                         int i2 = i * new_width;
03997                                         int i3 = (2 * half_width - i) * new_width;
03998                                         for (int j = 0; j < (width + 2 * half_width); j++) {
03999                                                 int k1 = cur_k + i2 + j;
04000                                                 int k2 = cur_k + i3 + j;
04001                                                 old_img[k1] = old_img[k2];
04002                                         }
04003 
04004                                         i2 = (height + half_width + i) * new_width;
04005                                         i3 = (height + half_width - 2 - i) * new_width;
04006                                         for (int j = 0; j < (width + 2 * half_width); j++) {
04007                                                 int k1 = cur_k + i2 + j;
04008                                                 int k2 = cur_k + i3 + j;
04009                                                 old_img[k1] = old_img[k2];
04010                                         }
04011                                 }
04012                         }
04013 
04014                         size_t idx;
04015                         for (int k = 0; k < slicenum; k++) {
04016                                 int cur_k = (k + half_width) * new_slice_size;
04017 
04018                                 for (int i = 0; i < height; i++) {
04019                                         int cur_i = (i + half_width) * new_width;
04020 
04021                                         for (int j = 0; j < width; j++) {
04022                                                 float f1 = 0;
04023                                                 float f2 = 0;
04024                                                 int k1 = cur_k + cur_i + (j + half_width);
04025 
04026                                                 for (int p = zstart; p <= zend; p++) {
04027                                                         int cur_p1 = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
04028                                                         int cur_p2 = (k + half_width + p) * new_slice_size;
04029 
04030                                                         for (int m = -half_width; m <= half_width; m++) {
04031                                                                 int cur_m1 = (m + half_width) * (2 * half_width + 1);
04032                                                                 int cur_m2 = cur_p2 + cur_i + m * new_width + j + half_width;
04033 
04034                                                                 for (int n = -half_width; n <= half_width; n++) {
04035                                                                         int k = cur_p1 + cur_m1 + (n + half_width);
04036                                                                         int k2 = cur_m2 + n;
04037                                                                         float f3 = Util::square(old_img[k1] - old_img[k2]);
04038 
04039                                                                         f3 = mask[k] * (1.0f / (1 + f3 / value_sigma));
04040                                                                         f1 += f3;
04041                                                                         int l1 = cur_m2 + n;
04042                                                                         f2 += f3 * old_img[l1];
04043                                                                 }
04044 
04045                                                                 idx = k * height * width + i * width + j;
04046                                                                 new_img[idx] = f2 / f1;
04047                                                         }
04048                                                 }
04049                                         }
04050                                 }
04051                         }
04052                         iter++;
04053                 }
04054                 if( mask ) {
04055                         free(mask);
04056                         mask = 0;
04057                 }
04058 
04059                 if( old_img ) {
04060                         free(old_img);
04061                         old_img = 0;
04062                 }
04063         }
04064 
04065         image->update();
04066 }


Member Data Documentation

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

Definition at line 136 of file processor.cpp.


The documentation for this class was generated from the following files:
Generated on Thu Dec 9 13:48:03 2010 for EMAN2 by  doxygen 1.3.9.1