#include <cmp.h>
Inheritance diagram for EMAN::OptVarianceCmp:
Public Member Functions | |
OptVarianceCmp () | |
float | cmp (EMData *image, EMData *with) const |
To compare 'image' with another image passed in through its parameters. | |
string | get_name () const |
Get the Cmp's name. | |
string | get_desc () const |
TypeDict | get_param_types () const |
Get Cmp parameter information in a dictionary. | |
float | get_scale () const |
float | get_shift () const |
Static Public Member Functions | |
static Cmp * | NEW () |
Static Public Attributes | |
static const string | NAME = "optvariance" |
Private Attributes | |
float | scale |
float | shift |
Generally, 'this' should be noisy and 'with' should be less noisy. linear scaling (mx + b) of the densities in 'this' is performed to produce the smallest possible variance between images.
If keepzero is set, then zero pixels are left at zero (b is not added). if matchfilt is set, then 'with' is filtered so its radial power spectrum matches 'this' If invert is set, then (y-b)/m is applied to the second image rather than mx+b to the first.
To modify 'this' to match the operation performed here, scale should be applied first, then b should be added
Definition at line 403 of file cmp.h.
EMAN::OptVarianceCmp::OptVarianceCmp | ( | ) | [inline] |
To compare 'image' with another image passed in through its parameters.
An optional transformation may be used to transform the 2 images.
image | The first image to be compared. | |
with | The second image to be comppared. |
Implements EMAN::Cmp.
Definition at line 734 of file cmp.cpp.
References b, EMAN::Util::calc_least_square_fit(), EMAN::EMData::calc_radial_dist(), EMAN::EMData::do_fft(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_const_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), ImageDimensionException, nx, EMAN::Cmp::params, EMAN::EMData::ri2ap(), scale, EMAN::EMData::set_attr(), EMAN::Dict::set_default(), shift, square, EMAN::Util::square(), EMAN::Cmp::validate_input_args(), EMAN::EMData::write_image(), x, and y.
00735 { 00736 ENTERFUNC; 00737 validate_input_args(image, with); 00738 00739 int keepzero = params.set_default("keepzero", 1); 00740 int invert = params.set_default("invert",0); 00741 int matchfilt = params.set_default("matchfilt",1); 00742 int matchamp = params.set_default("matchamp",0); 00743 int radweight = params.set_default("radweight",0); 00744 int dbug = params.set_default("debug",0); 00745 00746 size_t size = (size_t)image->get_xsize() * image->get_ysize() * image->get_zsize(); 00747 00748 00749 EMData *with2=NULL; 00750 if (matchfilt) { 00751 EMData *a = image->do_fft(); 00752 EMData *b = with->do_fft(); 00753 00754 vector <float> rfa=a->calc_radial_dist(a->get_ysize()/2,0.0f,1.0f,1); 00755 vector <float> rfb=b->calc_radial_dist(b->get_ysize()/2,0.0f,1.0f,1); 00756 00757 float avg=0; 00758 for (size_t i=0; i<a->get_ysize()/2.0f; i++) { 00759 rfa[i]=(rfb[i]==0?0.0f:(rfa[i]/rfb[i])); 00760 avg+=rfa[i]; 00761 } 00762 00763 avg/=a->get_ysize()/2.0f; 00764 for (size_t i=0; i<a->get_ysize()/2.0f; i++) { 00765 if (rfa[i]>avg*10.0) rfa[i]=10.0; // If some particular location has a small but non-zero value, we don't want to overcorrect it 00766 } 00767 rfa[0]=0.0; 00768 00769 if (dbug) b->write_image("a.hdf",-1); 00770 00771 b->apply_radial_func(0.0f,1.0f/a->get_ysize(),rfa); 00772 with2=b->do_ift(); 00773 00774 if (dbug) b->write_image("a.hdf",-1); 00775 if (dbug) a->write_image("a.hdf",-1); 00776 00777 /* if (dbug) { 00778 FILE *out=fopen("a.txt","w"); 00779 for (int i=0; i<a->get_ysize()/2.0; i++) fprintf(out,"%d\t%f\n",i,rfa[i]); 00780 fclose(out); 00781 00782 out=fopen("b.txt","w"); 00783 for (int i=0; i<a->get_ysize()/2.0; i++) fprintf(out,"%d\t%f\n",i,rfb[i]); 00784 fclose(out); 00785 }*/ 00786 00787 00788 delete a; 00789 delete b; 00790 00791 if (dbug) { 00792 with2->write_image("a.hdf",-1); 00793 image->write_image("a.hdf",-1); 00794 } 00795 00796 // with2->process_inplace("matchfilt",Dict("to",this)); 00797 // x_data = with2->get_data(); 00798 } 00799 00800 // This applies the individual Fourier amplitudes from 'image' and 00801 // applies them to 'with' 00802 if (matchamp) { 00803 EMData *a = image->do_fft(); 00804 EMData *b = with->do_fft(); 00805 size_t size2 = (size_t)a->get_xsize() * a->get_ysize() * a->get_zsize(); 00806 00807 a->ri2ap(); 00808 b->ri2ap(); 00809 00810 const float *const ad=a->get_const_data(); 00811 float * bd=b->get_data(); 00812 00813 for (size_t i=0; i<size2; i+=2) bd[i]=ad[i]; 00814 b->update(); 00815 00816 b->ap2ri(); 00817 with2=b->do_ift(); 00818 //with2->write_image("a.hdf",-1); 00819 delete a; 00820 delete b; 00821 } 00822 00823 const float * x_data; 00824 if (with2) x_data=with2->get_const_data(); 00825 else x_data = with->get_const_data(); 00826 const float *const y_data = image->get_const_data(); 00827 00828 size_t nx = image->get_xsize(); 00829 float m = 0; 00830 float b = 0; 00831 00832 // This will write the x vs y file used to calculate the density 00833 // optimization. This behavior may change in the future 00834 if (dbug) { 00835 FILE *out=fopen("dbug.optvar.txt","w"); 00836 if (out) { 00837 for (size_t i=0; i<size; i++) { 00838 if ( !keepzero || (x_data[i] && y_data[i])) fprintf(out,"%g\t%g\n",x_data[i],y_data[i]); 00839 } 00840 fclose(out); 00841 } 00842 } 00843 00844 00845 Util::calc_least_square_fit(size, x_data, y_data, &m, &b, keepzero); 00846 if (m == 0) { 00847 m = FLT_MIN; 00848 } 00849 b = -b / m; 00850 m = 1.0f / m; 00851 00852 // While negative slopes are really not a valid comparison in most cases, we 00853 // still want to detect these instances, so this if is removed 00854 /* if (m < 0) { 00855 b = 0; 00856 m = 1000.0; 00857 }*/ 00858 00859 double result = 0; 00860 int count = 0; 00861 00862 if (radweight) { 00863 if (image->get_zsize()!=1) throw ImageDimensionException("radweight option is 2D only"); 00864 if (keepzero) { 00865 for (size_t i = 0,y=0; i < size; y++) { 00866 for (size_t x=0; x<nx; i++,x++) { 00867 if (y_data[i] && x_data[i]) { 00868 #ifdef _WIN32 00869 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(_hypot((float)x,(float)y)+nx/4.0); 00870 else result += Util::square((x_data[i] * m) + b - y_data[i])*(_hypot((float)x,(float)y)+nx/4.0); 00871 #else 00872 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(hypot((float)x,(float)y)+nx/4.0); 00873 else result += Util::square((x_data[i] * m) + b - y_data[i])*(hypot((float)x,(float)y)+nx/4.0); 00874 #endif 00875 count++; 00876 } 00877 } 00878 } 00879 result/=count; 00880 } 00881 else { 00882 for (size_t i = 0,y=0; i < size; y++) { 00883 for (size_t x=0; x<nx; i++,x++) { 00884 #ifdef _WIN32 00885 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(_hypot((float)x,(float)y)+nx/4.0); 00886 else result += Util::square((x_data[i] * m) + b - y_data[i])*(_hypot((float)x,(float)y)+nx/4.0); 00887 #else 00888 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(hypot((float)x,(float)y)+nx/4.0); 00889 else result += Util::square((x_data[i] * m) + b - y_data[i])*(hypot((float)x,(float)y)+nx/4.0); 00890 #endif 00891 } 00892 } 00893 result = result / size; 00894 } 00895 } 00896 else { 00897 if (keepzero) { 00898 for (size_t i = 0; i < size; i++) { 00899 if (y_data[i] && x_data[i]) { 00900 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m); 00901 else result += Util::square((x_data[i] * m) + b - y_data[i]); 00902 count++; 00903 } 00904 } 00905 result/=count; 00906 } 00907 else { 00908 for (size_t i = 0; i < size; i++) { 00909 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m); 00910 else result += Util::square((x_data[i] * m) + b - y_data[i]); 00911 } 00912 result = result / size; 00913 } 00914 } 00915 scale = m; 00916 shift = b; 00917 00918 image->set_attr("ovcmp_m",m); 00919 image->set_attr("ovcmp_b",b); 00920 if (with2) delete with2; 00921 EXITFUNC; 00922 00923 #if 0 00924 return (1 - result); 00925 #endif 00926 00927 return static_cast<float>(result); 00928 }
string EMAN::OptVarianceCmp::get_desc | ( | ) | const [inline, virtual] |
string EMAN::OptVarianceCmp::get_name | ( | ) | const [inline, virtual] |
TypeDict EMAN::OptVarianceCmp::get_param_types | ( | ) | const [inline, virtual] |
Get Cmp parameter information in a dictionary.
Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.
Implements EMAN::Cmp.
Definition at line 425 of file cmp.h.
References EMAN::EMObject::INT, and EMAN::TypeDict::put().
00426 { 00427 TypeDict d; 00428 d.put("invert", EMObject::INT, "If set, 'with' is rescaled rather than 'this'. 'this' should still be the noisier image. (default=0)"); 00429 d.put("keepzero", EMObject::INT, "If set, zero pixels will not be adjusted in the linear density optimization. (default=1)"); 00430 d.put("matchfilt", EMObject::INT, "If set, with will be filtered so its radial power spectrum matches 'this' before density optimization of this. (default=1)"); 00431 d.put("matchamp", EMObject::INT, "Takes per-pixel Fourier amplitudes from self and imposes them on the target, but leaves the phases alone. (default=0)"); 00432 d.put("radweight", EMObject::INT, "Upweight variances closer to the edge of the image. (default=0)"); 00433 d.put("debug", EMObject::INT, "Performs various debugging actions if set."); 00434 return d; 00435 }
float EMAN::OptVarianceCmp::get_scale | ( | ) | const [inline] |
float EMAN::OptVarianceCmp::get_shift | ( | ) | const [inline] |
static Cmp* EMAN::OptVarianceCmp::NEW | ( | ) | [inline, static] |
Definition at line 420 of file cmp.h.
References OptVarianceCmp().
00421 { 00422 return new OptVarianceCmp(); 00423 }
const string OptVarianceCmp::NAME = "optvariance" [static] |
float EMAN::OptVarianceCmp::scale [mutable, private] |
float EMAN::OptVarianceCmp::shift [mutable, private] |