#include <processor.h>
Inheritance diagram for EMAN::GradientPlaneRemoverProcessor:
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 = "filter.gradientPlaneRemover" |
mask[in] | optional EMData object to mask the pixels used to fit the plane | |
changeZero[in] | optional bool to specify if the zero value pixels are modified | |
planeParam[out] | optional return parameters [nx, ny, nz, cx, cy, cz] for the fitted plane defined as (x-cx)*nx+(y-cy)*ny+(z-cz)*nz=0 |
Definition at line 3438 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 3452 of file processor.h. 03453 { 03454 return "Remove gradient by least square plane fit"; 03455 }
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 3443 of file processor.h. Referenced by process_inplace(). 03444 {
03445 return NAME;
03446 }
|
|
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 3457 of file processor.h. References EMAN::TypeDict::put(). 03458 { 03459 TypeDict d; 03460 d.put("mask", EMObject::EMDATA, "mask object: nonzero pixel positions will be used to fit plane. default = 0"); 03461 d.put("changeZero", EMObject::INT, "if zero pixels are modified when removing gradient. default = 0"); 03462 d.put("planeParam", EMObject::FLOATARRAY, "fitted plane parameters output"); 03463 return d; 03464 }
|
|
Definition at line 3447 of file processor.h. 03448 { 03449 return new GradientPlaneRemoverProcessor(); 03450 }
|
|
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 2648 of file processor.cpp. References dm, EMAN::EMData::get_data(), get_name(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Dict::has_key(), ImageDimensionException, LOGERR, LOGWARN, nx, ny, EMAN::EMData::update(), and V. 02649 { 02650 if (!image) { 02651 LOGWARN("NULL Image"); 02652 return; 02653 } 02654 02655 int nz = image->get_zsize(); 02656 if (nz > 1) { 02657 LOGERR("%s Processor doesn't support 3D model", get_name().c_str()); 02658 throw ImageDimensionException("3D map not supported"); 02659 } 02660 02661 int nx = image->get_xsize(); 02662 int ny = image->get_ysize(); 02663 float *d = image->get_data(); 02664 EMData *mask = 0; 02665 float *dm = 0; 02666 if (params.has_key("mask")) { 02667 mask = params["mask"]; 02668 if (nx!=mask->get_xsize() || ny!=mask->get_ysize()) { 02669 LOGERR("%s Processor requires same size mask image", get_name().c_str()); 02670 throw ImageDimensionException("wrong size mask image"); 02671 } 02672 dm = mask->get_data(); 02673 } 02674 int count = 0; 02675 if (dm) { 02676 for(int i=0; i<nx*ny; i++) { 02677 if(dm[i]) count++; 02678 } 02679 } 02680 else { 02681 count = nx * ny; 02682 } 02683 if(count<3) { 02684 LOGERR("%s Processor requires at least 3 pixels to fit a plane", get_name().c_str()); 02685 throw ImageDimensionException("too few usable pixels to fit a plane"); 02686 } 02687 // Allocate the working space 02688 gsl_vector *S=gsl_vector_calloc(3); 02689 gsl_matrix *A=gsl_matrix_calloc(count,3); 02690 gsl_matrix *V=gsl_matrix_calloc(3,3); 02691 02692 double m[3] = {0, 0, 0}; 02693 int index=0; 02694 if (dm) { 02695 for(int j=0; j<ny; j++){ 02696 for(int i=0; i<nx; i++){ 02697 int ij=j*nx+i; 02698 if(dm[ij]) { 02699 m[0]+=i; // x 02700 m[1]+=j; // y 02701 m[2]+=d[ij]; // z 02702 /*printf("index=%d/%d\ti,j=%d,%d\tval=%g\txm,ym,zm=%g,%g,%g\n", \ 02703 index,count,i,j,d[ij],m[0]/(index+1),m[1]/(index+1),m[2]/(index+1));*/ 02704 index++; 02705 } 02706 } 02707 } 02708 } 02709 else { 02710 for(int j=0; j<ny; j++){ 02711 for(int i=0; i<nx; i++){ 02712 int ij=j*nx+i; 02713 m[0]+=i; // x 02714 m[1]+=j; // y 02715 m[2]+=d[ij]; // z 02716 /*printf("index=%d/%d\ti,j=%d,%d\tval=%g\txm,ym,zm=%g,%g,%g\n", \ 02717 index,count,i,j,d[ij],m[0]/(index+1),m[1]/(index+1),m[2]/(index+1));*/ 02718 index++; 02719 } 02720 } 02721 } 02722 02723 for(int i=0; i<3; i++) m[i]/=count; // compute center of the plane 02724 02725 index=0; 02726 if (dm) { 02727 for(int j=0; j<ny; j++){ 02728 for(int i=0; i<nx; i++){ 02729 int ij=j*nx+i; 02730 if(dm[ij]) { 02731 //printf("index=%d/%d\ti,j=%d,%d\tval=%g\n",index,count,i,j,d[index]); 02732 gsl_matrix_set(A,index,0,i-m[0]); 02733 gsl_matrix_set(A,index,1,j-m[1]); 02734 gsl_matrix_set(A,index,2,d[ij]-m[2]); 02735 index++; 02736 } 02737 } 02738 } 02739 mask->update(); 02740 } 02741 else { 02742 for(int j=0; j<ny; j++){ 02743 for(int i=0; i<nx; i++){ 02744 int ij=j*nx+i; 02745 //printf("index=%d/%d\ti,j=%d,%d\tval=%g\n",index,count,i,j,d[index]); 02746 gsl_matrix_set(A,index,0,i-m[0]); 02747 gsl_matrix_set(A,index,1,j-m[1]); 02748 gsl_matrix_set(A,index,2,d[ij]-m[2]); 02749 index++; 02750 } 02751 } 02752 } 02753 02754 // SVD decomposition and use the V vector associated with smallest singular value as the plan normal 02755 gsl_linalg_SV_decomp_jacobi(A, V, S); 02756 02757 double n[3]; 02758 for(int i=0; i<3; i++) n[i] = gsl_matrix_get(V, i, 2); 02759 02760 #ifdef DEBUG 02761 printf("S=%g,%g,%g\n",gsl_vector_get(S,0), gsl_vector_get(S,1), gsl_vector_get(S,2)); 02762 printf("V[0,:]=%g,%g,%g\n",gsl_matrix_get(V,0,0), gsl_matrix_get(V,0,1),gsl_matrix_get(V,0,2)); 02763 printf("V[1,:]=%g,%g,%g\n",gsl_matrix_get(V,1,0), gsl_matrix_get(V,1,1),gsl_matrix_get(V,1,2)); 02764 printf("V[2,:]=%g,%g,%g\n",gsl_matrix_get(V,2,0), gsl_matrix_get(V,2,1),gsl_matrix_get(V,2,2)); 02765 printf("Fitted plane: p0=%g,%g,%g\tn=%g,%g,%g\n",m[0],m[1],m[2],n[0],n[1],n[2]); 02766 #endif 02767 02768 int changeZero = 0; 02769 if (params.has_key("changeZero")) changeZero = params["changeZero"]; 02770 if (changeZero) { 02771 for(int j=0; j<nx; j++){ 02772 for(int i=0; i<ny; i++){ 02773 int ij = j*nx+i; 02774 d[ij]-=static_cast<float>(-((i-m[0])*n[0]+(j-m[1])*n[1])/n[2]+m[2]); 02775 } 02776 } 02777 } 02778 else { 02779 for(int j=0; j<nx; j++){ 02780 for(int i=0; i<ny; i++){ 02781 int ij = j*nx+i; 02782 if(d[ij]) d[ij]-=static_cast<float>(-((i-m[0])*n[0]+(j-m[1])*n[1])/n[2]+m[2]); 02783 } 02784 } 02785 } 02786 image->update(); 02787 // set return plane parameters 02788 vector< float > planeParam; 02789 planeParam.resize(6); 02790 for(int i=0; i<3; i++) planeParam[i] = static_cast<float>(n[i]); 02791 for(int i=0; i<3; i++) planeParam[i+3] = static_cast<float>(m[i]); 02792 params["planeParam"]=EMObject(planeParam); 02793 }
|
|
Definition at line 124 of file processor.cpp. |