#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 3817 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 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 }
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 3821 of file processor.h. 03822 {
03823 return NAME;
03824 }
|
|
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 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 }
|
|
Definition at line 3831 of file processor.h. 03832 { 03833 return new BilateralProcessor(); 03834 }
|
|
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 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 }
|
|
Definition at line 136 of file processor.cpp. |