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


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


Member Function Documentation

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

03401 {
03402         if (!image) {
03403                 LOGWARN("NULL Image");
03404                 return;
03405         }
03406 
03407         float distance_sigma = params["distance_sigma"];
03408         float value_sigma = params["value_sigma"];
03409         int max_iter = params["niter"];
03410         int half_width = params["half_width"];
03411 
03412         if (half_width < distance_sigma) {
03413                 LOGWARN("localwidth(=%d) should be larger than distance_sigma=(%f)\n",
03414                                                         half_width, distance_sigma);
03415         }
03416 
03417         distance_sigma *= distance_sigma;
03418 
03419         float image_sigma = image->get_attr("sigma");
03420         if (image_sigma > value_sigma) {
03421                 LOGWARN("image sigma(=%f) should be smaller than value_sigma=(%f)\n",
03422                                                         image_sigma, value_sigma);
03423         }
03424         value_sigma *= value_sigma;
03425 
03426         int nx = image->get_xsize();
03427         int ny = image->get_ysize();
03428         int nz = image->get_zsize();
03429 
03430         if(nz==1) {     //for 2D image
03431                 int width=nx, height=ny;
03432 
03433                 int i,j,m,n;
03434 
03435                 float tempfloat1,tempfloat2,tempfloat3;
03436                 int   index1,index2,index;
03437                 int   Iter;
03438                 int   tempint1,tempint3;
03439 
03440                 tempint1=width;
03441                 tempint3=width+2*half_width;
03442 
03443                 float* mask=(float*)calloc((2*half_width+1)*(2*half_width+1),sizeof(float));
03444                 float* OrgImg=(float*)calloc((2*half_width+width)*(2*half_width+height),sizeof(float));
03445                 float* NewImg=image->get_data();
03446 
03447                 for(m=-(half_width);m<=half_width;m++)
03448                         for(n=-(half_width);n<=half_width;n++) {
03449                    index=(m+half_width)*(2*half_width+1)+(n+half_width);
03450                    mask[index]=exp((float)(-(m*m+n*n)/distance_sigma/2.0));
03451                 }
03452 
03453                 //printf("entering bilateral filtering process \n");
03454 
03455                 Iter=0;
03456                 while(Iter<max_iter) {
03457                         for(i=0;i<height;i++)
03458                         for(j=0;j<width;j++) {
03459                                 index1=(i+half_width)*tempint3+(j+half_width);
03460                                         index2=i*tempint1+j;
03461                                 OrgImg[index1]=NewImg[index2];
03462                         }
03463 
03464                         // Mirror Padding
03465                         for(i=0;i<height;i++){
03466                                 for(j=0;j<half_width;j++) OrgImg[(i+half_width)*tempint3+(j)]=OrgImg[(i+half_width)*tempint3+(2*half_width-j)];
03467                                 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)];
03468                         }
03469                         for(i=0;i<half_width;i++){
03470                                 for(j=0;j<(width+2*half_width);j++) OrgImg[i*tempint3+j]=OrgImg[(2*half_width-i)*tempint3+j];
03471                                 for(j=0;j<(width+2*half_width);j++) OrgImg[(i+height+half_width)*tempint3+j]=OrgImg[(height+half_width-2-i)*tempint3+j];
03472                         }
03473 
03474                         //printf("finish mirror padding process \n");
03475                         //now mirror padding have been done
03476 
03477                         for(i=0;i<height;i++){
03478                                 //printf("now processing the %d th row \n",i);
03479                                 for(j=0;j<width;j++){
03480                                         tempfloat1=0.0; tempfloat2=0.0;
03481                                         for(m=-(half_width);m<=half_width;m++)
03482                                                 for(n=-(half_width);n<=half_width;n++){
03483                                                         index =(m+half_width)*(2*half_width+1)+(n+half_width);
03484                                                         index1=(i+half_width)*tempint3+(j+half_width);
03485                                                         index2=(i+half_width+m)*tempint3+(j+half_width+n);
03486                                                         tempfloat3=(OrgImg[index1]-OrgImg[index2])*(OrgImg[index1]-OrgImg[index2]);
03487 
03488                                                         tempfloat3=mask[index]*(1.0f/(1+tempfloat3/value_sigma));       // Lorentz kernel
03489                                                         //tempfloat3=mask[index]*exp(tempfloat3/Sigma2/(-2.0)); // Guassian kernel
03490                                                         tempfloat1+=tempfloat3;
03491 
03492                                                         tempfloat2+=tempfloat3*OrgImg[(i+half_width+m)*tempint3+(j+half_width+n)];
03493                                         }
03494                                         NewImg[i*width+j]=tempfloat2/tempfloat1;
03495                                 }
03496                         }
03497                         Iter++;
03498             }
03499 
03500             //printf("have finished %d  th iteration\n ",Iter);
03501 //              doneData();
03502                 free(mask);
03503                 free(OrgImg);
03504                 // end of BilaFilter routine
03505 
03506         }
03507         else {  //3D case
03508                 int width = nx;
03509                 int height = ny;
03510                 int slicenum = nz;
03511 
03512                 int slice_size = width * height;
03513                 int new_width = width + 2 * half_width;
03514                 int new_slice_size = (width + 2 * half_width) * (height + 2 * half_width);
03515 
03516                 int width1 = 2 * half_width + 1;
03517                 int mask_size = width1 * width1;
03518                 int old_img_size = (2 * half_width + width) * (2 * half_width + height);
03519 
03520                 int zstart = -half_width;
03521                 int zend = -half_width;
03522                 int is_3d = 0;
03523                 if (nz > 1) {
03524                         mask_size *= width1;
03525                         old_img_size *= (2 * half_width + slicenum);
03526                         zend = half_width;
03527                         is_3d = 1;
03528                 }
03529 
03530                 float *mask = (float *) calloc(mask_size, sizeof(float));
03531                 float *old_img = (float *) calloc(old_img_size, sizeof(float));
03532 
03533                 float *new_img = image->get_data();
03534 
03535                 for (int p = zstart; p <= zend; p++) {
03536                         int cur_p = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
03537 
03538                         for (int m = -half_width; m <= half_width; m++) {
03539                                 int cur_m = (m + half_width) * (2 * half_width + 1) + half_width;
03540 
03541                                 for (int n = -half_width; n <= half_width; n++) {
03542                                         int l = cur_p + cur_m + n;
03543                                         mask[l] = exp((float) (-(m * m + n * n + p * p * is_3d) / distance_sigma / 2.0f));
03544                                 }
03545                         }
03546                 }
03547 
03548                 int iter = 0;
03549                 while (iter < max_iter) {
03550                         for (int k = 0; k < slicenum; k++) {
03551                                 int cur_k1 = (k + half_width) * new_slice_size * is_3d;
03552                                 int cur_k2 = k * slice_size;
03553 
03554                                 for (int i = 0; i < height; i++) {
03555                                         int cur_i1 = (i + half_width) * new_width;
03556                                         int cur_i2 = i * width;
03557 
03558                                         for (int j = 0; j < width; j++) {
03559                                                 int k1 = cur_k1 + cur_i1 + (j + half_width);
03560                                                 int k2 = cur_k2 + cur_i2 + j;
03561                                                 old_img[k1] = new_img[k2];
03562                                         }
03563                                 }
03564                         }
03565 
03566                         for (int k = 0; k < slicenum; k++) {
03567                                 int cur_k = (k + half_width) * new_slice_size * is_3d;
03568 
03569                                 for (int i = 0; i < height; i++) {
03570                                         int cur_i = (i + half_width) * new_width;
03571 
03572                                         for (int j = 0; j < half_width; j++) {
03573                                                 int k1 = cur_k + cur_i + j;
03574                                                 int k2 = cur_k + cur_i + (2 * half_width - j);
03575                                                 old_img[k1] = old_img[k2];
03576                                         }
03577 
03578                                         for (int j = 0; j < half_width; j++) {
03579                                                 int k1 = cur_k + cur_i + (width + half_width + j);
03580                                                 int k2 = cur_k + cur_i + (width + half_width - j - 2);
03581                                                 old_img[k1] = old_img[k2];
03582                                         }
03583                                 }
03584 
03585 
03586                                 for (int i = 0; i < half_width; i++) {
03587                                         int i2 = i * new_width;
03588                                         int i3 = (2 * half_width - i) * new_width;
03589                                         for (int j = 0; j < (width + 2 * half_width); j++) {
03590                                                 int k1 = cur_k + i2 + j;
03591                                                 int k2 = cur_k + i3 + j;
03592                                                 old_img[k1] = old_img[k2];
03593                                         }
03594 
03595                                         i2 = (height + half_width + i) * new_width;
03596                                         i3 = (height + half_width - 2 - i) * new_width;
03597                                         for (int j = 0; j < (width + 2 * half_width); j++) {
03598                                                 int k1 = cur_k + i2 + j;
03599                                                 int k2 = cur_k + i3 + j;
03600                                                 old_img[k1] = old_img[k2];
03601                                         }
03602                                 }
03603                         }
03604 
03605                         size_t idx;
03606                         for (int k = 0; k < slicenum; k++) {
03607                                 int cur_k = (k + half_width) * new_slice_size;
03608 
03609                                 for (int i = 0; i < height; i++) {
03610                                         int cur_i = (i + half_width) * new_width;
03611 
03612                                         for (int j = 0; j < width; j++) {
03613                                                 float f1 = 0;
03614                                                 float f2 = 0;
03615                                                 int k1 = cur_k + cur_i + (j + half_width);
03616 
03617                                                 for (int p = zstart; p <= zend; p++) {
03618                                                         int cur_p1 = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
03619                                                         int cur_p2 = (k + half_width + p) * new_slice_size;
03620 
03621                                                         for (int m = -half_width; m <= half_width; m++) {
03622                                                                 int cur_m1 = (m + half_width) * (2 * half_width + 1);
03623                                                                 int cur_m2 = cur_p2 + cur_i + m * new_width + j + half_width;
03624 
03625                                                                 for (int n = -half_width; n <= half_width; n++) {
03626                                                                         int k = cur_p1 + cur_m1 + (n + half_width);
03627                                                                         int k2 = cur_m2 + n;
03628                                                                         float f3 = Util::square(old_img[k1] - old_img[k2]);
03629 
03630                                                                         f3 = mask[k] * (1.0f / (1 + f3 / value_sigma));
03631                                                                         f1 += f3;
03632                                                                         int l1 = cur_m2 + n;
03633                                                                         f2 += f3 * old_img[l1];
03634                                                                 }
03635 
03636                                                                 idx = k * height * width + i * width + j;
03637                                                                 new_img[idx] = f2 / f1;
03638                                                         }
03639                                                 }
03640                                         }
03641                                 }
03642                         }
03643                         iter++;
03644                 }
03645                 if( mask ) {
03646                         free(mask);
03647                         mask = 0;
03648                 }
03649 
03650                 if( old_img ) {
03651                         free(old_img);
03652                         old_img = 0;
03653                 }
03654         }
03655 
03656         image->update();
03657 }

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

03739                 {
03740                         return "bilateral";
03741                 }

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

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

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

Definition at line 3748 of file processor.h.

03749                 {
03750                         return new BilateralProcessor();
03751                 }

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

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

03754                 {
03755                         TypeDict d;
03756                         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.");
03757                         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.");
03758                         d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
03759                         d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
03760                         return d;
03761                 }


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

Generated on Sat Nov 21 02:20:31 2009 for EMAN2 by  doxygen 1.5.6