#include <processor.h>
Inheritance diagram for EMAN::BilateralProcessor:


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 | |
| Processor * | NEW () |
Static Public Attributes | |
| const string | NAME = "bilateral" |
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 3958 of file processor.h.
|
|
Get the descrition of this specific processor. This function must be overwritten by a subclass.
Implements EMAN::Processor. Definition at line 3967 of file processor.h. 03968 {
03969 return "Bilateral processing on 2D or 3D volume data. Bilateral processing does non-linear weighted averaging processing within a certain window. ";
03970 }
|
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 3962 of file processor.h. 03963 {
03964 return NAME;
03965 }
|
|
|
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 3977 of file processor.h. References EMAN::TypeDict::put(). 03978 {
03979 TypeDict d;
03980 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.");
03981 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.");
03982 d.put("niter", EMObject::INT, "how many times to apply this processing on your data.");
03983 d.put("half_width", EMObject::INT, "processing window size = (2 * half_widthh + 1) ^ 3.");
03984 return d;
03985 }
|
|
|
Definition at line 3972 of file processor.h. 03973 {
03974 return new BilateralProcessor();
03975 }
|
|
|
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.
Implements EMAN::Processor. Definition at line 3867 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(). 03868 {
03869 if (!image) {
03870 LOGWARN("NULL Image");
03871 return;
03872 }
03873
03874 float distance_sigma = params["distance_sigma"];
03875 float value_sigma = params["value_sigma"];
03876 int max_iter = params["niter"];
03877 int half_width = params["half_width"];
03878
03879 if (half_width < distance_sigma) {
03880 LOGWARN("localwidth(=%d) should be larger than distance_sigma=(%f)\n",
03881 half_width, distance_sigma);
03882 }
03883
03884 distance_sigma *= distance_sigma;
03885
03886 float image_sigma = image->get_attr("sigma");
03887 if (image_sigma > value_sigma) {
03888 LOGWARN("image sigma(=%f) should be smaller than value_sigma=(%f)\n",
03889 image_sigma, value_sigma);
03890 }
03891 value_sigma *= value_sigma;
03892
03893 int nx = image->get_xsize();
03894 int ny = image->get_ysize();
03895 int nz = image->get_zsize();
03896
03897 if(nz==1) { //for 2D image
03898 int width=nx, height=ny;
03899
03900 int i,j,m,n;
03901
03902 float tempfloat1,tempfloat2,tempfloat3;
03903 int index1,index2,index;
03904 int Iter;
03905 int tempint1,tempint3;
03906
03907 tempint1=width;
03908 tempint3=width+2*half_width;
03909
03910 float* mask=(float*)calloc((2*half_width+1)*(2*half_width+1),sizeof(float));
03911 float* OrgImg=(float*)calloc((2*half_width+width)*(2*half_width+height),sizeof(float));
03912 float* NewImg=image->get_data();
03913
03914 for(m=-(half_width);m<=half_width;m++)
03915 for(n=-(half_width);n<=half_width;n++) {
03916 index=(m+half_width)*(2*half_width+1)+(n+half_width);
03917 mask[index]=exp((float)(-(m*m+n*n)/distance_sigma/2.0));
03918 }
03919
03920 //printf("entering bilateral filtering process \n");
03921
03922 Iter=0;
03923 while(Iter<max_iter) {
03924 for(i=0;i<height;i++)
03925 for(j=0;j<width;j++) {
03926 index1=(i+half_width)*tempint3+(j+half_width);
03927 index2=i*tempint1+j;
03928 OrgImg[index1]=NewImg[index2];
03929 }
03930
03931 // Mirror Padding
03932 for(i=0;i<height;i++){
03933 for(j=0;j<half_width;j++) OrgImg[(i+half_width)*tempint3+(j)]=OrgImg[(i+half_width)*tempint3+(2*half_width-j)];
03934 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)];
03935 }
03936 for(i=0;i<half_width;i++){
03937 for(j=0;j<(width+2*half_width);j++) OrgImg[i*tempint3+j]=OrgImg[(2*half_width-i)*tempint3+j];
03938 for(j=0;j<(width+2*half_width);j++) OrgImg[(i+height+half_width)*tempint3+j]=OrgImg[(height+half_width-2-i)*tempint3+j];
03939 }
03940
03941 //printf("finish mirror padding process \n");
03942 //now mirror padding have been done
03943
03944 for(i=0;i<height;i++){
03945 //printf("now processing the %d th row \n",i);
03946 for(j=0;j<width;j++){
03947 tempfloat1=0.0; tempfloat2=0.0;
03948 for(m=-(half_width);m<=half_width;m++)
03949 for(n=-(half_width);n<=half_width;n++){
03950 index =(m+half_width)*(2*half_width+1)+(n+half_width);
03951 index1=(i+half_width)*tempint3+(j+half_width);
03952 index2=(i+half_width+m)*tempint3+(j+half_width+n);
03953 tempfloat3=(OrgImg[index1]-OrgImg[index2])*(OrgImg[index1]-OrgImg[index2]);
03954
03955 tempfloat3=mask[index]*(1.0f/(1+tempfloat3/value_sigma)); // Lorentz kernel
03956 //tempfloat3=mask[index]*exp(tempfloat3/Sigma2/(-2.0)); // Guassian kernel
03957 tempfloat1+=tempfloat3;
03958
03959 tempfloat2+=tempfloat3*OrgImg[(i+half_width+m)*tempint3+(j+half_width+n)];
03960 }
03961 NewImg[i*width+j]=tempfloat2/tempfloat1;
03962 }
03963 }
03964 Iter++;
03965 }
03966
03967 //printf("have finished %d th iteration\n ",Iter);
03968 // doneData();
03969 free(mask);
03970 free(OrgImg);
03971 // end of BilaFilter routine
03972
03973 }
03974 else { //3D case
03975 int width = nx;
03976 int height = ny;
03977 int slicenum = nz;
03978
03979 int slice_size = width * height;
03980 int new_width = width + 2 * half_width;
03981 int new_slice_size = (width + 2 * half_width) * (height + 2 * half_width);
03982
03983 int width1 = 2 * half_width + 1;
03984 int mask_size = width1 * width1;
03985 int old_img_size = (2 * half_width + width) * (2 * half_width + height);
03986
03987 int zstart = -half_width;
03988 int zend = -half_width;
03989 int is_3d = 0;
03990 if (nz > 1) {
03991 mask_size *= width1;
03992 old_img_size *= (2 * half_width + slicenum);
03993 zend = half_width;
03994 is_3d = 1;
03995 }
03996
03997 float *mask = (float *) calloc(mask_size, sizeof(float));
03998 float *old_img = (float *) calloc(old_img_size, sizeof(float));
03999
04000 float *new_img = image->get_data();
04001
04002 for (int p = zstart; p <= zend; p++) {
04003 int cur_p = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
04004
04005 for (int m = -half_width; m <= half_width; m++) {
04006 int cur_m = (m + half_width) * (2 * half_width + 1) + half_width;
04007
04008 for (int n = -half_width; n <= half_width; n++) {
04009 int l = cur_p + cur_m + n;
04010 mask[l] = exp((float) (-(m * m + n * n + p * p * is_3d) / distance_sigma / 2.0f));
04011 }
04012 }
04013 }
04014
04015 int iter = 0;
04016 while (iter < max_iter) {
04017 for (int k = 0; k < slicenum; k++) {
04018 size_t cur_k1 = (size_t)(k + half_width) * new_slice_size * is_3d;
04019 int cur_k2 = k * slice_size;
04020
04021 for (int i = 0; i < height; i++) {
04022 int cur_i1 = (i + half_width) * new_width;
04023 int cur_i2 = i * width;
04024
04025 for (int j = 0; j < width; j++) {
04026 size_t k1 = cur_k1 + cur_i1 + (j + half_width);
04027 int k2 = cur_k2 + cur_i2 + j;
04028 old_img[k1] = new_img[k2];
04029 }
04030 }
04031 }
04032
04033 for (int k = 0; k < slicenum; k++) {
04034 size_t cur_k = (k + half_width) * new_slice_size * is_3d;
04035
04036 for (int i = 0; i < height; i++) {
04037 int cur_i = (i + half_width) * new_width;
04038
04039 for (int j = 0; j < half_width; j++) {
04040 size_t k1 = cur_k + cur_i + j;
04041 size_t k2 = cur_k + cur_i + (2 * half_width - j);
04042 old_img[k1] = old_img[k2];
04043 }
04044
04045 for (int j = 0; j < half_width; j++) {
04046 size_t k1 = cur_k + cur_i + (width + half_width + j);
04047 size_t k2 = cur_k + cur_i + (width + half_width - j - 2);
04048 old_img[k1] = old_img[k2];
04049 }
04050 }
04051
04052
04053 for (int i = 0; i < half_width; i++) {
04054 int i2 = i * new_width;
04055 int i3 = (2 * half_width - i) * new_width;
04056 for (int j = 0; j < (width + 2 * half_width); j++) {
04057 size_t k1 = cur_k + i2 + j;
04058 size_t k2 = cur_k + i3 + j;
04059 old_img[k1] = old_img[k2];
04060 }
04061
04062 i2 = (height + half_width + i) * new_width;
04063 i3 = (height + half_width - 2 - i) * new_width;
04064 for (int j = 0; j < (width + 2 * half_width); j++) {
04065 size_t k1 = cur_k + i2 + j;
04066 size_t k2 = cur_k + i3 + j;
04067 old_img[k1] = old_img[k2];
04068 }
04069 }
04070 }
04071
04072 size_t idx;
04073 for (int k = 0; k < slicenum; k++) {
04074 size_t cur_k = (k + half_width) * new_slice_size;
04075
04076 for (int i = 0; i < height; i++) {
04077 int cur_i = (i + half_width) * new_width;
04078
04079 for (int j = 0; j < width; j++) {
04080 float f1 = 0;
04081 float f2 = 0;
04082 size_t k1 = cur_k + cur_i + (j + half_width);
04083
04084 for (int p = zstart; p <= zend; p++) {
04085 size_t cur_p1 = (p + half_width) * (2 * half_width + 1) * (2 * half_width + 1);
04086 size_t cur_p2 = (k + half_width + p) * new_slice_size;
04087
04088 for (int m = -half_width; m <= half_width; m++) {
04089 size_t cur_m1 = (m + half_width) * (2 * half_width + 1);
04090 size_t cur_m2 = cur_p2 + cur_i + m * new_width + j + half_width;
04091
04092 for (int n = -half_width; n <= half_width; n++) {
04093 size_t k = cur_p1 + cur_m1 + (n + half_width);
04094 size_t k2 = cur_m2 + n;
04095 float f3 = Util::square(old_img[k1] - old_img[k2]);
04096
04097 f3 = mask[k] * (1.0f / (1 + f3 / value_sigma));
04098 f1 += f3;
04099 size_t l1 = cur_m2 + n;
04100 f2 += f3 * old_img[l1];
04101 }
04102
04103 idx = (size_t)k * height * width + i * width + j;
04104 new_img[idx] = f2 / f1;
04105 }
04106 }
04107 }
04108 }
04109 }
04110 iter++;
04111 }
04112 if( mask ) {
04113 free(mask);
04114 mask = 0;
04115 }
04116
04117 if( old_img ) {
04118 free(old_img);
04119 old_img = 0;
04120 }
04121 }
04122
04123 image->update();
04124 }
|
|
|
Definition at line 141 of file processor.cpp. |
1.3.9.1