EMAN2
Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all 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]

Public Member Functions

void process_inplace (EMData *image)
 To process an image in-place. More...
 
string get_name () const
 Get the processor's name. More...
 
string get_desc () const
 Get the descrition of this specific processor. More...
 
TypeDict get_param_types () const
 Get processor parameter information in a dictionary. More...
 
- Public Member Functions inherited from EMAN::Processor
virtual ~Processor ()
 
virtual EMDataprocess (const EMData *const image)
 To proccess an image out-of-place. More...
 
virtual void process_list_inplace (vector< EMData * > &images)
 To process multiple images using the same algorithm. More...
 
virtual Dict get_params () const
 Get the processor parameters in a key/value dictionary. More...
 
virtual void set_params (const Dict &new_params)
 Set the processor parameters using a key/value dictionary. More...
 

Static Public Member Functions

static ProcessorNEW ()
 
- Static Public Member Functions inherited from EMAN::Processor
static string get_group_desc ()
 Get the description of this group of processors. More...
 
static void EMFourierFilterInPlace (EMData *fimage, Dict params)
 Compute a Fourier-filter processed image in place. More...
 
static EMDataEMFourierFilter (EMData *fimage, Dict params)
 Compute a Fourier-processor processed image without altering the original image. More...
 

Static Public Attributes

static const string NAME = "filter.bilateral"
 

Additional Inherited Members

- Public Types inherited from EMAN::Processor
enum  fourier_filter_types {
  TOP_HAT_LOW_PASS , TOP_HAT_HIGH_PASS , TOP_HAT_BAND_PASS , TOP_HOMOMORPHIC ,
  GAUSS_LOW_PASS , GAUSS_HIGH_PASS , GAUSS_BAND_PASS , GAUSS_INVERSE ,
  GAUSS_HOMOMORPHIC , BUTTERWORTH_LOW_PASS , BUTTERWORTH_HIGH_PASS , BUTTERWORTH_HOMOMORPHIC ,
  KAISER_I0 , KAISER_SINH , KAISER_I0_INVERSE , KAISER_SINH_INVERSE ,
  SHIFT , TANH_LOW_PASS , TANH_HIGH_PASS , TANH_HOMOMORPHIC ,
  TANH_BAND_PASS , RADIAL_TABLE , CTF_
}
 Fourier filter Processor type enum. More...
 
- Protected Attributes inherited from EMAN::Processor
Dict params
 

Detailed Description

Bilateral processing on 2D or 3D volume data.

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

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

Definition at line 5792 of file processor.h.

Member Function Documentation

◆ get_desc()

string EMAN::BilateralProcessor::get_desc ( ) const
inlinevirtual

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

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

◆ get_name()

string EMAN::BilateralProcessor::get_name ( ) const
inlinevirtual

Get the processor's name.

Each processor is identified by a unique name.

Returns
The processor's name.

Implements EMAN::Processor.

Definition at line 5796 of file processor.h.

5797 {
5798 return NAME;
5799 }
static const string NAME
Definition: processor.h:5821

References NAME.

◆ get_param_types()

TypeDict EMAN::BilateralProcessor::get_param_types ( ) const
inlinevirtual

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

5812 {
5813 TypeDict d;
5814 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.");
5815 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.");
5816 d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
5817 d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
5818 return d;
5819 }
TypeDict is a dictionary to store <string, EMObject::ObjectType> pair.
Definition: emobject.h:305
void put(const string &key, EMObject::ObjectType o, const string &desc="")
Definition: emobject.h:330

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

◆ NEW()

static Processor * EMAN::BilateralProcessor::NEW ( )
inlinestatic

Definition at line 5806 of file processor.h.

5807 {
5808 return new BilateralProcessor();
5809 }
Bilateral processing on 2D or 3D volume data.
Definition: processor.h:5793

◆ process_inplace()

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
imageThe image to be processed.

Implements EMAN::Processor.

Definition at line 5334 of file processor.cpp.

5335{
5336 if (!image) {
5337 LOGWARN("NULL Image");
5338 return;
5339 }
5340
5341 float distance_sigma = params["distance_sigma"];
5342 float value_sigma = params["value_sigma"];
5343 int max_iter = params["niter"];
5344 int half_width = params["half_width"];
5345
5346 if (half_width < distance_sigma) {
5347 LOGWARN("localwidth(=%d) should be larger than distance_sigma=(%f)\n",
5348 half_width, distance_sigma);
5349 }
5350
5351 distance_sigma *= distance_sigma;
5352
5353 float image_sigma = image->get_attr("sigma");
5354 if (image_sigma > value_sigma) {
5355 LOGWARN("image sigma(=%f) should be smaller than value_sigma=(%f)\n",
5356 image_sigma, value_sigma);
5357 }
5358 value_sigma *= value_sigma;
5359
5360 int nx = image->get_xsize();
5361 int ny = image->get_ysize();
5362 int nz = image->get_zsize();
5363
5364 if(nz==1) { //for 2D image
5365 int width=nx, height=ny;
5366
5367 int i,j,m,n;
5368
5369 float tempfloat1,tempfloat2,tempfloat3;
5370 int index1,index2,index;
5371 int Iter;
5372 int tempint1,tempint3;
5373
5374 tempint1=width;
5375 tempint3=width+2*half_width;
5376
5377 float* mask=(float*)calloc((2*half_width+1)*(2*half_width+1),sizeof(float));
5378 float* OrgImg=(float*)calloc((2*half_width+width)*(2*half_width+height),sizeof(float));
5379 float* NewImg=image->get_data();
5380
5381 for(m=-(half_width);m<=half_width;m++)
5382 for(n=-(half_width);n<=half_width;n++) {
5383 index=(m+half_width)*(2*half_width+1)+(n+half_width);
5384 mask[index]=exp((float)(-(m*m+n*n)/distance_sigma/2.0));
5385 }
5386
5387 //printf("entering bilateral filtering process \n");
5388
5389 Iter=0;
5390 while(Iter<max_iter) {
5391 for(i=0;i<height;i++)
5392 for(j=0;j<width;j++) {
5393 index1=(i+half_width)*tempint3+(j+half_width);
5394 index2=i*tempint1+j;
5395 OrgImg[index1]=NewImg[index2];
5396 }
5397
5398 // Mirror Padding
5399 for(i=0;i<height;i++){
5400 for(j=0;j<half_width;j++) OrgImg[(i+half_width)*tempint3+(j)]=OrgImg[(i+half_width)*tempint3+(2*half_width-j)];
5401 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)];
5402 }
5403 for(i=0;i<half_width;i++){
5404 for(j=0;j<(width+2*half_width);j++) OrgImg[i*tempint3+j]=OrgImg[(2*half_width-i)*tempint3+j];
5405 for(j=0;j<(width+2*half_width);j++) OrgImg[(i+height+half_width)*tempint3+j]=OrgImg[(height+half_width-2-i)*tempint3+j];
5406 }
5407
5408 //printf("finish mirror padding process \n");
5409 //now mirror padding have been done
5410
5411 for(i=0;i<height;i++){
5412 //printf("now processing the %d th row \n",i);
5413 for(j=0;j<width;j++){
5414 tempfloat1=0.0; tempfloat2=0.0;
5415 for(m=-(half_width);m<=half_width;m++)
5416 for(n=-(half_width);n<=half_width;n++){
5417 index =(m+half_width)*(2*half_width+1)+(n+half_width);
5418 index1=(i+half_width)*tempint3+(j+half_width);
5419 index2=(i+half_width+m)*tempint3+(j+half_width+n);
5420 tempfloat3=(OrgImg[index1]-OrgImg[index2])*(OrgImg[index1]-OrgImg[index2]);
5421
5422 tempfloat3=mask[index]*(1.0f/(1+tempfloat3/value_sigma)); // Lorentz kernel
5423 //tempfloat3=mask[index]*exp(tempfloat3/Sigma2/(-2.0)); // Guassian kernel
5424 tempfloat1+=tempfloat3;
5425
5426 tempfloat2+=tempfloat3*OrgImg[(i+half_width+m)*tempint3+(j+half_width+n)];
5427 }
5428 NewImg[i*width+j]=tempfloat2/tempfloat1;
5429 }
5430 }
5431 Iter++;
5432 }
5433
5434 //printf("have finished %d th iteration\n ",Iter);
5435// doneData();
5436 free(mask);
5437 free(OrgImg);
5438 // end of BilaFilter routine
5439
5440 }
5441 else { //3D case
5442 int width = nx;
5443 int height = ny;
5444 int slicenum = nz;
5445
5446 int slice_size = width * height;
5447 int new_width = width + 2 * half_width;
5448 int new_slice_size = (width + 2 * half_width) * (height + 2 * half_width);
5449
5450 int width1 = 2 * half_width + 1;
5451 int mask_size = width1 * width1;
5452 int old_img_size = (2 * half_width + width) * (2 * half_width + height);
5453
5454 int zstart = -half_width;
5455 int zend = -half_width;
5456 int is_3d = 0;
5457 if (nz > 1) {
5458 mask_size *= width1;
5459 old_img_size *= (2 * half_width + slicenum);
5460 zend = half_width;
5461 is_3d = 1;
5462 }
5463
5464 float *mask = (float *) calloc(mask_size, sizeof(float));
5465 float *old_img = (float *) calloc(old_img_size, sizeof(float));
5466
5467 float *new_img = image->get_data();
5468
5469 for (int p = zstart; p <= zend; p++) {
5470 int cur_p = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
5471
5472 for (int m = -half_width; m <= half_width; m++) {
5473 int cur_m = (m + half_width) * (2 * half_width + 1) + half_width;
5474
5475 for (int n = -half_width; n <= half_width; n++) {
5476 int l = cur_p + cur_m + n;
5477 mask[l] = exp((float) (-(m * m + n * n + p * p * is_3d) / distance_sigma / 2.0f));
5478 }
5479 }
5480 }
5481
5482 int iter = 0;
5483 while (iter < max_iter) {
5484 for (int k = 0; k < slicenum; k++) {
5485 size_t cur_k1 = (size_t)(k + half_width) * new_slice_size * is_3d;
5486 int cur_k2 = k * slice_size;
5487
5488 for (int i = 0; i < height; i++) {
5489 int cur_i1 = (i + half_width) * new_width;
5490 int cur_i2 = i * width;
5491
5492 for (int j = 0; j < width; j++) {
5493 size_t k1 = cur_k1 + cur_i1 + (j + half_width);
5494 int k2 = cur_k2 + cur_i2 + j;
5495 old_img[k1] = new_img[k2];
5496 }
5497 }
5498 }
5499
5500 for (int k = 0; k < slicenum; k++) {
5501 size_t cur_k = (k + half_width) * new_slice_size * is_3d;
5502
5503 for (int i = 0; i < height; i++) {
5504 int cur_i = (i + half_width) * new_width;
5505
5506 for (int j = 0; j < half_width; j++) {
5507 size_t k1 = cur_k + cur_i + j;
5508 size_t k2 = cur_k + cur_i + (2 * half_width - j);
5509 old_img[k1] = old_img[k2];
5510 }
5511
5512 for (int j = 0; j < half_width; j++) {
5513 size_t k1 = cur_k + cur_i + (width + half_width + j);
5514 size_t k2 = cur_k + cur_i + (width + half_width - j - 2);
5515 old_img[k1] = old_img[k2];
5516 }
5517 }
5518
5519
5520 for (int i = 0; i < half_width; i++) {
5521 int i2 = i * new_width;
5522 int i3 = (2 * half_width - i) * new_width;
5523 for (int j = 0; j < (width + 2 * half_width); j++) {
5524 size_t k1 = cur_k + i2 + j;
5525 size_t k2 = cur_k + i3 + j;
5526 old_img[k1] = old_img[k2];
5527 }
5528
5529 i2 = (height + half_width + i) * new_width;
5530 i3 = (height + half_width - 2 - i) * new_width;
5531 for (int j = 0; j < (width + 2 * half_width); j++) {
5532 size_t k1 = cur_k + i2 + j;
5533 size_t k2 = cur_k + i3 + j;
5534 old_img[k1] = old_img[k2];
5535 }
5536 }
5537 }
5538
5539 size_t idx;
5540 for (int k = 0; k < slicenum; k++) {
5541 size_t cur_k = (k + half_width) * new_slice_size;
5542
5543 for (int i = 0; i < height; i++) {
5544 int cur_i = (i + half_width) * new_width;
5545
5546 for (int j = 0; j < width; j++) {
5547 float f1 = 0;
5548 float f2 = 0;
5549 size_t k1 = cur_k + cur_i + (j + half_width);
5550
5551 for (int p = zstart; p <= zend; p++) {
5552 size_t cur_p1 = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
5553 size_t cur_p2 = (k + half_width + p) * new_slice_size;
5554
5555 for (int m = -half_width; m <= half_width; m++) {
5556 size_t cur_m1 = (m + half_width) * (2 * half_width + 1);
5557 size_t cur_m2 = cur_p2 + cur_i + m * new_width + j + half_width;
5558
5559 for (int n = -half_width; n <= half_width; n++) {
5560 size_t k = cur_p1 + cur_m1 + (n + half_width);
5561 size_t k2 = cur_m2 + n;
5562 float f3 = Util::square(old_img[k1] - old_img[k2]);
5563
5564 f3 = mask[k] * (1.0f / (1 + f3 / value_sigma));
5565 f1 += f3;
5566 size_t l1 = cur_m2 + n;
5567 f2 += f3 * old_img[l1];
5568 }
5569
5570 idx = (size_t)k * height * width + i * width + j;
5571 new_img[idx] = f2 / f1;
5572 }
5573 }
5574 }
5575 }
5576 }
5577 iter++;
5578 }
5579 if( mask ) {
5580 free(mask);
5581 mask = 0;
5582 }
5583
5584 if( old_img ) {
5585 free(old_img);
5586 old_img = 0;
5587 }
5588 }
5589
5590 image->update();
5591}
static int square(int n)
Calculate a number's square.
Definition: util.h:736
#define LOGWARN
Definition: log.h:53

References LOGWARN, EMAN::Processor::params, and EMAN::Util::square().

Member Data Documentation

◆ NAME

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

Definition at line 5821 of file processor.h.

Referenced by get_name().


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