The Flutter Shutter Code Optimizer
|
00001 /*best_snapshot_average.cpp*/ 00002 /* 00003 * Copyright 2013 IPOL Image Processing On Line http://www.ipol.im/ 00004 * 00005 * This program is free software: you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation, either version 3 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 */ 00030 #include <math.h> 00031 #include "best_snapshot_average.h" 00032 00033 00034 #define eps 0.001//epsilon definition, for integral evaluation. 00035 00036 00037 #ifndef ABS 00038 00041 #define ABS(x) (((x) > 0) ? (x) : (-(x))) 00042 #endif 00043 00044 #ifndef M_PI 00045 00048 #define M_PI 3.14159265358979323846 00049 #endif 00050 00051 00052 00053 00054 00055 00061 00084 double best_snapshot_average(int flag_motion_model, double s, 00085 double proba_handcrafted_0) 00086 { 00088 //initialization 00089 double best_deltat=0; 00090 double best_E=best_snapshot_average_energy(0, flag_motion_model, s, 00091 proba_handcrafted_0); 00092 double current_E=best_E; 00093 double v_max=s; 00094 if (flag_motion_model==0) v_max=4*s; 00095 00096 // main loop for enegy minimization : scanning on \Deltat values 00097 for (double deltat=(2/v_max)/100; deltat<1.999/v_max; 00098 deltat=deltat+(2/v_max)/100) 00099 { 00100 //(at v_max)deltat the energy is infinite. 00101 current_E=best_snapshot_average_energy(deltat, flag_motion_model, s, 00102 proba_handcrafted_0); 00103 if (current_E<best_E) 00104 { 00105 best_E=current_E; 00106 best_deltat=deltat; 00107 } 00108 } 00109 return(best_deltat); 00110 00111 } 00112 00113 00114 00115 00121 00143 double best_snapshot_average_energy(double deltat, int flag_motion_model, 00144 double s, double proba_handcrafted_0) 00145 { 00147 00148 double v_max=s; 00149 if (flag_motion_model==0) v_max=4*s; 00150 00151 if (flag_motion_model!=2) 00152 { 00154 00155 double a=0;// Using parity. 00156 double b=v_max; 00157 double h=(b-a)/2; 00158 double s1=best_snapshot_average_integrand(a,deltat)* 00159 proba_motion_model(a,s,proba_handcrafted_0, 00160 flag_motion_model)+ 00161 best_snapshot_average_integrand(b,deltat)* 00162 proba_motion_model(b,s,proba_handcrafted_0, 00163 flag_motion_model); 00164 double s2=0; 00165 double s4=best_snapshot_average_integrand(a+h,deltat)* 00166 proba_motion_model(a+h,s,proba_handcrafted_0, 00167 flag_motion_model); 00168 double tn=h*(s1+4*s4)/3; 00169 double ta=tn+eps*tn; 00170 int zh=2; 00171 int j; 00172 00173 00175 while (ABS(ta-tn)>eps*ABS(tn)) 00176 { 00177 ta=tn; 00178 zh=2*zh; 00179 h=h/2; 00180 s2=s2+s4; 00181 s4=0; 00182 j=1; 00183 while (j<=zh) 00184 { 00185 s4=s4+best_snapshot_average_integrand(a+j*h,deltat)* 00186 proba_motion_model(a+j*h,s,proba_handcrafted_0, 00187 flag_motion_model); 00188 j=j+2; 00189 } 00190 tn = h*(s1+2*s2+4*s4)/3; 00191 } 00192 return(tn); 00193 } 00194 else 00200 { 00201 return(best_snapshot_average_integrand(0,deltat)*proba_handcrafted_0+ 00202 best_snapshot_average_integrand(s,deltat)* 00203 (1-proba_handcrafted_0)); 00204 } 00205 00206 } 00207 00208 00214 00226 double best_snapshot_average_integrand(double v, double deltat) 00227 { 00228 00232 double a=0; 00233 double b=M_PI; 00234 double h=(b-a)/2; 00235 double s1=best_snapshot_integrand(a,v,deltat)+ 00236 best_snapshot_integrand(b,v,deltat); 00237 double s2=0; 00238 double s4=best_snapshot_integrand(a+h,v,deltat); 00239 double tn=h*(s1+4*s4)/3; 00240 double ta=tn+eps*tn; 00241 int zh=2; 00242 int j; 00243 00245 while (ABS(ta-tn)>eps*ABS(tn)) 00246 { 00247 ta=tn; 00248 zh=2*zh; 00249 h=h/2; 00250 s2=s2+s4; 00251 s4=0; 00252 j=1; 00253 while (j<=zh) 00254 { 00255 s4=s4+best_snapshot_integrand(a+j*h,v,deltat); 00256 j=j+2; 00257 } 00258 tn = h*(s1+2*s2+4*s4)/3; 00259 } 00260 return(2*tn); 00261 } 00262 00263 00264 00265 00271 00283 double best_snapshot_integrand(double xi, double v, double deltat) 00284 { 00285 double xivdt_2=xi*v*deltat/2; 00286 double sinc=1; 00287 if (xi*v!=0) 00288 { 00289 sinc=sin(xivdt_2)/xivdt_2; 00290 } 00291 if (deltat!=0 && sinc!=0) 00292 { 00293 return(1/(deltat*sinc*sinc)); 00294 } 00295 else 00296 { 00297 return(99999); //Dummy case, called if deltat=0 (the energy is infinite) 00298 } 00299 00300 } 00301 00302 00303 00304 00310 00324 double proba_motion_model(double v, double s, double proba_handcrafted_0, 00325 int flag_motion_model) 00326 { 00327 00328 if (flag_motion_model==0) return(exp(-v*v/(2*s*s))); 00330 if (flag_motion_model==1) return(1/(2*s)); 00331 else return(proba_handcrafted_0*(v==0)+(1-proba_handcrafted_0)*(ABS(v)==s)); 00334 }