#include <processor.h>


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 Processor * | NEW () |
Bilateral processing does non-linear weighted averaging processing within a certain window.
| 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.
| 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.
| 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.
Implements EMAN::Processor.
Definition at line 3738 of file processor.h.
| string EMAN::BilateralProcessor::get_desc | ( | ) | const [inline, virtual] |
Get the descrition of this specific processor.
This function must be overwritten by a subclass.
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] |
| 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.
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 }
1.5.6