#include <cmp.h>


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 () |
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 351 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 526 of file cmp.cpp.
References EMAN::EMData::ap2ri(), EMAN::EMData::apply_radial_func(), b, EMAN::Util::calc_least_square_fit(), EMAN::EMData::calc_radial_dist(), EMAN::EMData::do_fft(), EMAN::EMData::do_ift(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_const_data(), EMAN::EMData::get_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::EMData::update(), EMAN::Cmp::validate_input_args(), EMAN::EMData::write_image(), x, and y.
00527 { 00528 ENTERFUNC; 00529 validate_input_args(image, with); 00530 00531 int keepzero = params.set_default("keepzero", 1); 00532 int invert = params.set_default("invert",0); 00533 int matchfilt = params.set_default("matchfilt",1); 00534 int matchamp = params.set_default("matchamp",0); 00535 int radweight = params.set_default("radweight",0); 00536 int dbug = params.set_default("debug",0); 00537 00538 size_t size = image->get_xsize() * image->get_ysize() * image->get_zsize(); 00539 00540 00541 EMData *with2=NULL; 00542 if (matchfilt) { 00543 EMData *a = image->do_fft(); 00544 EMData *b = with->do_fft(); 00545 00546 vector <float> rfa=a->calc_radial_dist(a->get_ysize()/2,0.0f,1.0f,1); 00547 vector <float> rfb=b->calc_radial_dist(b->get_ysize()/2,0.0f,1.0f,1); 00548 00549 float avg=0; 00550 for (size_t i=0; i<a->get_ysize()/2.0f; i++) { 00551 rfa[i]=(rfb[i]==0?0.0f:(rfa[i]/rfb[i])); 00552 avg+=rfa[i]; 00553 } 00554 00555 avg/=a->get_ysize()/2.0f; 00556 for (size_t i=0; i<a->get_ysize()/2.0f; i++) { 00557 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 00558 } 00559 rfa[0]=0.0; 00560 00561 if (dbug) b->write_image("a.hdf",-1); 00562 00563 b->apply_radial_func(0.0f,1.0f/a->get_ysize(),rfa); 00564 with2=b->do_ift(); 00565 00566 if (dbug) b->write_image("a.hdf",-1); 00567 if (dbug) a->write_image("a.hdf",-1); 00568 00569 /* if (dbug) { 00570 FILE *out=fopen("a.txt","w"); 00571 for (int i=0; i<a->get_ysize()/2.0; i++) fprintf(out,"%d\t%f\n",i,rfa[i]); 00572 fclose(out); 00573 00574 out=fopen("b.txt","w"); 00575 for (int i=0; i<a->get_ysize()/2.0; i++) fprintf(out,"%d\t%f\n",i,rfb[i]); 00576 fclose(out); 00577 }*/ 00578 00579 00580 delete a; 00581 delete b; 00582 00583 if (dbug) { 00584 with2->write_image("a.hdf",-1); 00585 image->write_image("a.hdf",-1); 00586 } 00587 00588 // with2->process_inplace("matchfilt",Dict("to",this)); 00589 // x_data = with2->get_data(); 00590 } 00591 00592 // This applies the individual Fourier amplitudes from 'image' and 00593 // applies them to 'with' 00594 if (matchamp) { 00595 EMData *a = image->do_fft(); 00596 EMData *b = with->do_fft(); 00597 size_t size2 = a->get_xsize() * a->get_ysize() * a->get_zsize(); 00598 00599 a->ri2ap(); 00600 b->ri2ap(); 00601 00602 const float *const ad=a->get_const_data(); 00603 float * bd=b->get_data(); 00604 00605 for (size_t i=0; i<size2; i+=2) bd[i]=ad[i]; 00606 b->update(); 00607 00608 b->ap2ri(); 00609 with2=b->do_ift(); 00610 //with2->write_image("a.hdf",-1); 00611 delete a; 00612 delete b; 00613 } 00614 00615 const float * x_data; 00616 if (with2) x_data=with2->get_const_data(); 00617 else x_data = with->get_const_data(); 00618 const float *const y_data = image->get_const_data(); 00619 00620 size_t nx = image->get_xsize(); 00621 float m = 0; 00622 float b = 0; 00623 00624 // This will write the x vs y file used to calculate the density 00625 // optimization. This behavior may change in the future 00626 if (dbug) { 00627 FILE *out=fopen("dbug.optvar.txt","w"); 00628 if (out) { 00629 for (size_t i=0; i<size; i++) { 00630 if ( !keepzero || (x_data[i] && y_data[i])) fprintf(out,"%g\t%g\n",x_data[i],y_data[i]); 00631 } 00632 fclose(out); 00633 } 00634 } 00635 00636 00637 Util::calc_least_square_fit(size, x_data, y_data, &m, &b, keepzero); 00638 if (m == 0) { 00639 m = FLT_MIN; 00640 } 00641 b = -b / m; 00642 m = 1.0f / m; 00643 00644 // While negative slopes are really not a valid comparison in most cases, we 00645 // still want to detect these instances, so this if is removed 00646 /* if (m < 0) { 00647 b = 0; 00648 m = 1000.0; 00649 }*/ 00650 00651 double result = 0; 00652 int count = 0; 00653 00654 if (radweight) { 00655 if (image->get_zsize()!=1) throw ImageDimensionException("radweight option is 2D only"); 00656 if (keepzero) { 00657 for (size_t i = 0,y=0; i < size; y++) { 00658 for (size_t x=0; x<nx; i++,x++) { 00659 if (y_data[i] && x_data[i]) { 00660 #ifdef _WIN32 00661 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(_hypot((float)x,(float)y)+nx/4.0); 00662 else result += Util::square((x_data[i] * m) + b - y_data[i])*(_hypot((float)x,(float)y)+nx/4.0); 00663 #else 00664 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(hypot((float)x,(float)y)+nx/4.0); 00665 else result += Util::square((x_data[i] * m) + b - y_data[i])*(hypot((float)x,(float)y)+nx/4.0); 00666 #endif 00667 count++; 00668 } 00669 } 00670 } 00671 result/=count; 00672 } 00673 else { 00674 for (size_t i = 0,y=0; i < size; y++) { 00675 for (size_t x=0; x<nx; i++,x++) { 00676 #ifdef _WIN32 00677 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(_hypot((float)x,(float)y)+nx/4.0); 00678 else result += Util::square((x_data[i] * m) + b - y_data[i])*(_hypot((float)x,(float)y)+nx/4.0); 00679 #else 00680 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m)*(hypot((float)x,(float)y)+nx/4.0); 00681 else result += Util::square((x_data[i] * m) + b - y_data[i])*(hypot((float)x,(float)y)+nx/4.0); 00682 #endif 00683 } 00684 } 00685 result = result / size; 00686 } 00687 } 00688 else { 00689 if (keepzero) { 00690 for (size_t i = 0; i < size; i++) { 00691 if (y_data[i] && x_data[i]) { 00692 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m); 00693 else result += Util::square((x_data[i] * m) + b - y_data[i]); 00694 count++; 00695 } 00696 } 00697 result/=count; 00698 } 00699 else { 00700 for (size_t i = 0; i < size; i++) { 00701 if (invert) result += Util::square(x_data[i] - (y_data[i]-b)/m); 00702 else result += Util::square((x_data[i] * m) + b - y_data[i]); 00703 } 00704 result = result / size; 00705 } 00706 } 00707 scale = m; 00708 shift = b; 00709 00710 image->set_attr("ovcmp_m",m); 00711 image->set_attr("ovcmp_b",b); 00712 if (with2) delete with2; 00713 EXITFUNC; 00714 00715 #if 0 00716 return (1 - result); 00717 #endif 00718 00719 return static_cast<float>(result); 00720 }
| string EMAN::OptVarianceCmp::get_name | ( | ) | const [inline, virtual] |
| string EMAN::OptVarianceCmp::get_desc | ( | ) | const [inline, virtual] |
| static Cmp* EMAN::OptVarianceCmp::NEW | ( | ) | [inline, static] |
Definition at line 368 of file cmp.h.
References OptVarianceCmp().
00369 { 00370 return new OptVarianceCmp(); 00371 }
| 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 373 of file cmp.h.
References EMAN::EMObject::INT, and EMAN::TypeDict::put().
00374 { 00375 TypeDict d; 00376 d.put("invert", EMObject::INT, "If set, 'with' is rescaled rather than 'this'. 'this' should still be the noisier image. (default=0)"); 00377 d.put("keepzero", EMObject::INT, "If set, zero pixels will not be adjusted in the linear density optimization. (default=1)"); 00378 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)"); 00379 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)"); 00380 d.put("radweight", EMObject::INT, "Upweight variances closer to the edge of the image. (default=0)"); 00381 d.put("debug", EMObject::INT, "Performs various debugging actions if set."); 00382 return d; 00383 }
| float EMAN::OptVarianceCmp::get_scale | ( | ) | const [inline] |
| float EMAN::OptVarianceCmp::get_shift | ( | ) | const [inline] |
float EMAN::OptVarianceCmp::scale [mutable, private] |
float EMAN::OptVarianceCmp::shift [mutable, private] |
1.5.6