--- ray/src/util/evalglare.c 2016/07/14 17:32:12 2.3 +++ ray/src/util/evalglare.c 2018/11/27 18:08:24 2.10 @@ -1,7 +1,7 @@ #ifndef lint -static const char RCSid[] = "$Id: evalglare.c,v 2.3 2016/07/14 17:32:12 greg Exp $"; +static const char RCSid[] = "$Id: evalglare.c,v 2.10 2018/11/27 18:08:24 greg Exp $"; #endif -/* EVALGLARE V1.29 +/* EVALGLARE V2.08 * Evalglare Software License, Version 2.0 * * Copyright (c) 1995 - 2016 Fraunhofer ISE, EPFL. @@ -308,9 +308,48 @@ changed masking threshold to 0.05 cd/m2 */ /* evalglare.c, v1.29 2016/07/12 change threshold for the black corner to 2cd/m2. */ +/* evalglare.c, v1.30 2016/07/28 change zonal output: If just one zone is specified, only one zone shows up in the output (bug removal). + */ +/* evalglare.c, v1.31 2016/08/02 bug removal: default output did not calculate the amout of glare sources before and therefore no_glaresources was set to zero causing dgi,ugr being set to zero as well. Now renumbering of the glare sources and calculation of the amount of glare sources is done for all output versions. + */ +/* evalglare.c, v2.00 2016/11/15 add of a second fast calculation mode for annual calculations, activted by -2. Output: dgp,ugr + */ +/* evalglare.c, v2.01 2016/11/16 change of -2 option (now -2 dir_illum). External provision of the direct illuminance necessary, since the sun interpolation of daysim is causing problems in calculation of the background luminance. + */ +/* evalglare.c, v2.02 2017/02/28 change of warning message, when invalid exposure setting is found. Reason: tab removal is not in all cases the right measure - it depends which tool caused the invalid exposure entry */ + +/* evalglare.c, v2.03 2017/08/04 ad of -O option - disk replacement by providing luminance, not documented + */ + +/* evalglare.c, v2.04 2017/08/04 adding -q option: use of Ev/pi as background luminance. not documented. no combination with -n option!!! + */ + +/* evalglare.c, v2.05 2018/08/28 change of the -q option for the choice of the background luminance calculation mode: 0: CIE method (Ev-Edir)/pi, 1: mathematical correct average background luminance, 2: Ev/pi. +change of default options: +- cosinus weighted calculation of the background luminance (according to CIE) is now default. +- absolute threshold for the glare source detection is now default (2000cd/m2), based on study of C. Pierson + */ + +/* evalglare.c, v2.06 2018/08/29 +change of default value of multiplier b to 5.0, if task options (-t or -T ) are activated AND -b NOT used. To be downward compatible when using the task method. + */ + +/* evalglare.c, v2.07 2018/11/17 +bugfix: correction of error in the equations of PGSV_con and PGSV_sat +all three PGSV equations are calculated now +illuminance from the masking area (E_v_mask) is also printed +bugfix: in VCPs error fuction equation, value of 6.347 replaced by 6.374 + */ + +/* evalglare.c, v2.08 2018/11/27 +bugfix: checkroutine for same image size for the masking corrected + */ + + + #define EVALGLARE #define PROGNAME "evalglare" -#define VERSION "1.29 release 12.07.2016 by EPFL, J.Wienold" +#define VERSION "2.08 release 27.11.2018 by EPFL, J.Wienold" #define RELEASENAME PROGNAME " " VERSION @@ -1162,7 +1201,7 @@ float get_vcp(float dgr ) { float vcp; - vcp = 50 * erf((6.347 - 1.3227 * log(dgr)) / 1.414213562373) + 50; + vcp = 50 * erf((6.374 - 1.3227 * log(dgr)) / 1.414213562373) + 50; if (dgr > 750) { vcp = 0; } @@ -1197,7 +1236,13 @@ float get_ugr(pict * p, double lum_backg, int igs, int } } ugr = 8 * log10(0.25 / lum_backg * sum_glare); - + if (sum_glare==0) { + ugr=0.0; + } + if (lum_backg<=0) { + ugr=-99.0; + } + return ugr; } @@ -1327,18 +1372,23 @@ float get_cgi(pict * p, double E_v, double E_v_dir, in return cgi; } -/* subroutine for the calculation of the PGSV; is only applied, when masking is done, since it refers only to the window. Important: masking area must be the window! */ -float get_pgsv(double E_v, double E_mask,double omega_mask,double lum_mask_av) + + +/* subroutine for the calculation of the PGSV_con; is only applied, when masking is done, since it refers only to the window. Important: masking area must be the window! */ +float get_pgsv_con(double E_v, double E_mask,double omega_mask,double lum_mask_av, double Lavg) { - float pgsv; + float pgsv_con; double Lb; - Lb = (E_v-E_mask)/1.414213562373; +/* Lb = (E_v-E_mask)/3.14159265359; */ +/* Lb = (2*E_v-lum_mask_av*omega_mask)/(2*3.14159265359-omega_mask); */ + Lb = (2*3.14159265359*Lavg-lum_mask_av*omega_mask)/(2*3.14159265359-omega_mask); - pgsv =3.2*log10(lum_mask_av)-0.64*log10(omega_mask)+(0.79*log10(omega_mask)-0.61)*log10(Lb)-8.2 ; + pgsv_con =3.2*log10(lum_mask_av)-0.64*log10(omega_mask)+(0.79*log10(omega_mask)-0.61)*log10(Lb)-8.2 ; - return pgsv; + + return pgsv_con; } /* subroutine for the calculation of the PGSV_saturation; is only applied, when masking is done, since it refers only to the window. Important: masking area must be the window! */ @@ -1346,15 +1396,38 @@ float get_pgsv_sat(double E_v) { float pgsv_sat; - pgsv_sat =3.3-(0.57+3.3)/pow((1+E_v/1.414213562373/1250),1.7); + pgsv_sat =3.3-(0.57+3.3)/(1+pow(E_v/3.14159265359/1250,1.7)); return pgsv_sat; } +/* subroutine for the calculation of the PGSV; is only applied, when masking is done, since it refers only to the window. Important: masking area must be the window! */ +float get_pgsv(double E_v, double E_mask,double omega_mask,double lum_mask_av,double Ltask, double Lavg) +{ + float pgsv; + double Lb; +/* Lb = (E_v-E_mask)/3.14159265359; */ +/* Lb = (2*E_v-lum_mask_av*omega_mask)/(2*3.14159265359-omega_mask); */ + Lb = (2*3.14159265359*Lavg-lum_mask_av*omega_mask)/(2*3.14159265359-omega_mask); + + if (Lb==0.0 ) { + fprintf(stderr, " warning: Background luminance is 0 or masking area = full image! pgsv cannot be calculated (set to -99)!!\n"); + pgsv=-99; + }else{ + if ( (lum_mask_av/Lb) > (E_v/(3.14159265359*Ltask))) { + pgsv=get_pgsv_con(E_v,E_mask,omega_mask,lum_mask_av, Lavg); + }else{ + pgsv=get_pgsv_sat(E_v) ; + }} + return pgsv; +} + + + #ifdef EVALGLARE @@ -1369,12 +1442,12 @@ int main(int argc, char **argv) pict *pm = pict_create(); int skip_second_scan,calcfast,age_corr,cut_view,cut_view_type,calc_vill, output, detail_out2, x1,y1, fill, yfillmax, yfillmin, ext_vill, set_lum_max, set_lum_max2, img_corr,x_disk,y_disk,task_color, i_splitstart,zones,act_gsn,splitgs, - i_split, posindex_2, task_lum, checkfile, rval, i, i_max, x, y,x2,y2,x_zone,y_zone, i_z1, i_z2, + i_split, posindex_2, task_lum, checkfile, rval, i, i_max, x, y,x2,y2,x_zone,y_zone, i_z1, i_z2, thres_activate, igs, actual_igs, lastpixelwas_gs, icol, xt, yt, change,checkpixels, before_igs, sgs, splithigh,uniform_gs,x_max, y_max,y_mid, detail_out, posindex_picture, non_cos_lb, rx, ry, rmx,rmy,apply_disability,band_calc,band_color,masking,i_mask,no_glaresources,force; - double lum_total_max,age_corr_factor,age,dgp_ext,dgp,low_light_corr,omega_cos_contr, setvalue, lum_ideal, E_v_contr, sigma,om,delta_E, - E_vl_ext, lum_max, new_lum_max, r_center, ugp, ugr_exp, dgi_mod,lum_a, pgsv,E_v_mask,pgsv_sat,angle_disk,dist,n_corner_px,zero_corner_px, - search_pix, a1, a2, a3, a4, a5, c3, c1, c2, r_split, max_angle,r_actual,lum_actual, + double LUM_replace,lum_total_max,age_corr_factor,age,dgp_ext,dgp,low_light_corr,omega_cos_contr, setvalue, lum_ideal, E_v_contr, sigma,om,delta_E, + E_vl_ext, lum_max, new_lum_max, r_center, ugp, ugr_exp, dgi_mod,lum_a, E_v_mask,angle_disk,dist,n_corner_px,zero_corner_px, + search_pix, a1, a2, a3, a4, a5, c3, c1, c2, r_split, max_angle,r_actual,lum_actual,dir_ill, omegat, sang, E_v, E_v2, E_v_dir, avlum, act_lum, ang, angle_z1, angle_z2,per_95_band,per_75_band,pos, l_max, lum_backg, lum_backg_cos, omega_sources, lum_sources,per_75_mask,per_95_mask,per_75_z1,per_95_z1,per_75_z2,per_95_z2, lum, lum_source,teta,Lveil_cie,Lveil_cie_sum,disability_thresh,u_r,u_g,u_b,band_angle,band_avlum, @@ -1383,7 +1456,7 @@ int main(int argc, char **argv) lum_z1[1],lum_z1_av,lum_z1_std[1],lum_z1_median[1],omega_z1,bbox_z1[2], lum_z2[1],lum_z2_av,lum_z2_std[1],lum_z2_median[1],omega_z2,bbox_z2[2], lum_pos[1],lum_nopos_median[1],lum_pos_median[1],lum_pos2_median[1],lum_pos_mean,lum_pos2_mean; - float lum_task, lum_thres, dgi, vcp, cgi, ugr, limit, dgr, + float lum_task, lum_thres, dgi, vcp, cgi, ugr, limit, dgr,pgsv ,pgsv_sat,pgsv_con, abs_max, Lveil; char maskfile[500],file_out[500], file_out2[500], version[500]; char *cline; @@ -1423,6 +1496,7 @@ int main(int argc, char **argv) muc_rvar_clear(s_posweight2); /*set required user view parameters to invalid values*/ + dir_ill=0.0; delta_E=0.0; no_glaresources=0; n_corner_px=0; @@ -1444,6 +1518,7 @@ int main(int argc, char **argv) lum_band_av = 0.0; omega_band = 0.0; pgsv = 0.0 ; + pgsv_con = 0.0 ; pgsv_sat = 0.0 ; E_v_mask = 0.0; lum_z1_av = 0.0; @@ -1485,7 +1560,8 @@ int main(int argc, char **argv) omega_cos_contr = 0.0; lum_ideal = 0.0; max_angle = 0.2; - lum_thres = 5.0; + lum_thres = 2000.0; + lum_task = 0.0; task_lum = 0; sgs = 0; splithigh = 1; @@ -1503,7 +1579,7 @@ int main(int argc, char **argv) c1 = 5.87e-05; c2 = 0.092; c3 = 0.159; - non_cos_lb = 1; + non_cos_lb = 0; posindex_2 = 0; task_color = 0; limit = 50000.0; @@ -1525,6 +1601,8 @@ int main(int argc, char **argv) omega_mask=0.0; i_mask=0; actual_igs=0; + LUM_replace=0; + thres_activate=0; /* command line for output picture*/ cline = (char *) malloc(CLINEMAX+1); @@ -1575,6 +1653,7 @@ int main(int argc, char **argv) break; case 'b': lum_thres = atof(argv[++i]); + thres_activate = 1; break; case 'c': checkfile = 1; @@ -1663,10 +1742,25 @@ int main(int argc, char **argv) strcpy(file_out2, argv[++i]); /* printf("max lum set to %f\n",new_lum_max);*/ break; + case 'O': + img_corr = 1; + set_lum_max2 = 3; + x_disk = atoi(argv[++i]); + y_disk = atoi(argv[++i]); + angle_disk = atof(argv[++i]); + LUM_replace = atof(argv[++i]); + strcpy(file_out2, argv[++i]); +/* printf("max lum set to %f\n",new_lum_max);*/ + break; - case 'n': + +/* deactivated case 'n': non_cos_lb = 0; break; +*/ + case 'q': + non_cos_lb = atoi(argv[++i]); + break; case 't': task_lum = 1; @@ -1735,6 +1829,10 @@ int main(int argc, char **argv) case '1': output = 1; break; + case '2': + output = 2; + dir_ill = atof(argv[++i]); + break; case 'v': if (argv[i][2] == '\0') { @@ -1764,11 +1862,21 @@ int main(int argc, char **argv) } } +/* set multiplier for task method to 5, if not specified */ + +if ( task_lum == 1 && thres_activate == 0){ + lum_thres = 5.0; +} /*fast calculation, if gendgp_profile is used: No Vertical illuminance calculation, only dgp is calculated*/ -if (output == 1 && ext_vill == 1) { +if (output == 1 && ext_vill == 1 ) { calcfast=1; } + +if (output == 2 && ext_vill == 1 ) { + calcfast=2; + } + /*masking and zoning cannot be applied at the same time*/ if (masking ==1 && zones >0) { @@ -1829,7 +1937,7 @@ if (masking ==1 && zones >0) { if (masking == 1) { - if (!pict_get_xsize(p)==pict_get_xsize(pm) || !pict_get_ysize(p)==pict_get_ysize(pm)) { + if (pict_get_xsize(p)!=pict_get_xsize(pm) || pict_get_ysize(p)!=pict_get_ysize(pm)) { fprintf(stderr, "error: masking image has other resolution than main image ! \n"); fprintf(stderr, "size must be identical \n"); printf("resolution main image : %dx%d\n",pict_get_xsize(p),pict_get_ysize(p)); @@ -2057,8 +2165,9 @@ if (cut_view==2) { lum_pos_mean= lum_pos_mean/sang; lum_pos2_mean= lum_pos2_mean/sang; - if (set_lum_max2 >= 1 && E_v_contr > 0 && (E_vl_ext - E_v) > 0) { + if ((set_lum_max2 >= 1 && E_v_contr > 0 && (E_vl_ext - E_v) > 0 ) || set_lum_max2==3) { + if (set_lum_max2<3){ lum_ideal = (E_vl_ext - E_v + E_v_contr) / omega_cos_contr; if (set_lum_max2 == 2 && lum_ideal >= 2e9) { printf("warning! luminance of replacement pixels would be larger than 2e9 cd/m2. Value set to 2e9cd/m2!\n") ; @@ -2069,6 +2178,8 @@ if (cut_view==2) { } printf("change luminance values!! lum_ideal,setvalue,E_vl_ext,E_v,E_v_contr %f %f %f %f %f\n", lum_ideal, setvalue, E_vl_ext, E_v, E_v_contr); + }else{setvalue=LUM_replace; + } for (x = 0; x < pict_get_xsize(p); x++) @@ -2088,7 +2199,7 @@ if (cut_view==2) { pict_get_color(p, x, y)[BLU] = setvalue / 179.0; - }else{ if(set_lum_max2 ==2 ) { + }else{ if(set_lum_max2 >1 ) { r_actual =acos(DOT(pict_get_cached_dir(p, x_disk, y_disk), pict_get_cached_dir(p, x, y))) * 2; if (x_disk == x && y_disk==y ) r_actual=0.0; @@ -2101,9 +2212,7 @@ if (cut_view==2) { pict_get_color(p, x, y)[BLU] = setvalue / 179.0; - } - - + } } } } @@ -2219,9 +2328,12 @@ if (cut_view==1) { /* pict_write(p,"firstscan.pic"); */ -if (calcfast == 1 || search_pix <= 1.0) { + + +if (calcfast ==1 || search_pix <= 1.0 || calcfast == 2 ) { skip_second_scan=1; } + /* second glare source scan: combine glare sources facing each other */ change = 1; @@ -2396,7 +2508,7 @@ if (calcfast == 1 || search_pix <= 1.0) { /* calculation of direct vertical illuminance for CGI and for disability glare, coloring glare sources*/ - if (calcfast == 0) { + if (calcfast == 0 || calcfast == 2) { for (x = 0; x < pict_get_xsize(p); x++) for (y = 0; y < pict_get_ysize(p); y++) { if (pict_get_hangle(p, x, y, p->view.vdir, p->view.vup, &ang)) { @@ -2484,6 +2596,11 @@ if (calcfast == 1 || search_pix <= 1.0) { lum_backg = lum_backg_cos; } + if (non_cos_lb == 2) { + lum_backg = E_v / 3.1415927; + } + + /* file writing NOT here if (checkfile == 1) { pict_write(p, file_out); @@ -2493,7 +2610,6 @@ if (calcfast == 1 || search_pix <= 1.0) { /* print detailed output */ - if (detail_out == 1) { /* masking */ @@ -2536,12 +2652,24 @@ if (calcfast == 1 || search_pix <= 1.0) { muc_rvar_get_median(s_mask,lum_mask_median); muc_rvar_get_bounding_box(s_mask,bbox); /* PSGV only why masking of window is applied! */ - pgsv = get_pgsv(E_v, E_v_mask, omega_mask, lum_mask_av); + + + if (task_lum == 0 || lum_task == 0.0 ) { + fprintf(stderr, " warning: Task area not set or task luminance=0 ! pgsv cannot be calculated (set to -99)!!\n"); + pgsv = -99; + } else { + pgsv = get_pgsv(E_v, E_v_mask, omega_mask, lum_mask_av,lum_task,avlum); + } + + pgsv_con = get_pgsv_con(E_v, E_v_mask, omega_mask, lum_mask_av,avlum); pgsv_sat =get_pgsv_sat(E_v); - printf ("masking:no_pixels,omega,av_lum,median_lum,std_lum,perc_75,perc_95,lum_min,lum_max,pgsv,pgsv_sat: %i %f %f %f %f %f %f %f %f %f %f\n",i_mask,omega_mask,lum_mask_av,lum_mask_median[0],sqrt(lum_mask_std[0]),per_75_mask,per_95_mask,bbox[0],bbox[1],pgsv,pgsv_sat ); + if (detail_out == 1) { + + printf ("masking:no_pixels,omega,av_lum,median_lum,std_lum,perc_75,perc_95,lum_min,lum_max,pgsv_con,pgsv_sat,pgsv,Ev_mask: %i %f %f %f %f %f %f %f %f %f %f %f %f\n",i_mask,omega_mask,lum_mask_av,lum_mask_median[0],sqrt(lum_mask_std[0]),per_75_mask,per_95_mask,bbox[0],bbox[1],pgsv_con,pgsv_sat,pgsv,E_v_mask ); + + } - } /* zones */ @@ -2631,12 +2759,14 @@ if (calcfast == 1 || search_pix <= 1.0) { per_95_z1=lum_z1_median[0]; muc_rvar_get_median(s_z1,lum_z1_median); muc_rvar_get_bounding_box(s_z1,bbox_z1); - + if (detail_out == 1) { + printf ("zoning:z1_omega,z1_av_lum,z1_median_lum,z1_std_lum,z1_perc_75,z1_perc_95,z1_lum_min,z1_lum_max: %f %f %f %f %f %f %f %f\n",omega_z1,lum_z1_av,lum_z1_median[0],sqrt(lum_z1_std[0]),per_75_z1,per_95_z1,bbox_z1[0],bbox_z1[1] ); + if (zones == 2 ) { printf ("zoning:z2_omega,z2_av_lum,z2_median_lum,z2_std_lum,z2_perc_75,z2_perc_95,z2_lum_min,z2_lum_max: %f %f %f %f %f %f %f %f\n",omega_z2,lum_z2_av,lum_z2_median[0],sqrt(lum_z2_std[0]),per_75_z2,per_95_z2,bbox_z2[0],bbox_z2[1] ); - + } } } @@ -2650,6 +2780,8 @@ if (calcfast == 1 || search_pix <= 1.0) { no_glaresources=i; /* glare sources */ + if (detail_out == 1) { + printf ("%i No pixels x-pos y-pos L_s Omega_s Posindx L_b L_t E_vert Edir Max_Lum Sigma xdir ydir zdir Eglare_cie Lveil_cie teta glare_zone\n", i); @@ -2814,8 +2946,15 @@ if (calcfast == 0) { if (E_vl_ext < 1000) { low_light_corr=1.0*exp(0.024*E_vl_ext-4)/(1+exp(0.024*E_vl_ext-4)); } else {low_light_corr=1.0 ;} dgp =low_light_corr*dgp; - dgp =age_corr_factor*dgp; - printf("%f\n", dgp); + + if (calcfast == 2) { + + lum_backg_cos=(E_vl_ext-dir_ill)/3.1415927; + ugr = get_ugr(p, lum_backg_cos, igs, posindex_2); + printf("%f %f \n", dgp,ugr); + }else{ + printf("%f\n", dgp); + } }