28#include "hdrl_types.h"
29#include "hdrl_image.h"
30#include "hdrl_imagelist.h"
31#include "hdrl_utils.h"
33#include "hdrl_bpm_2d.h"
34#include "hdrl_prototyping.h"
82static cpl_image * hdrl_get_residuals_filtersmooth(cpl_size, cpl_size,
83 cpl_filter_mode, cpl_border_mode, cpl_image *, cpl_mask *);
84static cpl_image * hdrl_get_residuals_legendresmooth(
const cpl_image *,
int,
85 int,
int,
int,
int,
int) ;
92 cpl_filter_mode filter ;
93 cpl_border_mode border ;
105 hdrl_bpm_2d_method method ;
106} hdrl_bpm_2d_parameter;
109static hdrl_parameter_typeobj hdrl_bpm_2d_parameter_type = {
110 HDRL_PARAMETER_BPM_2D,
111 (hdrl_alloc *)&cpl_malloc,
112 (hdrl_free *)&cpl_free,
114 sizeof(hdrl_bpm_2d_parameter),
141 cpl_filter_mode filter,
142 cpl_border_mode border,
146 hdrl_bpm_2d_parameter * p = (hdrl_bpm_2d_parameter *)
147 hdrl_parameter_new(&hdrl_bpm_2d_parameter_type);
148 p->kappa_low = kappa_low ;
149 p->kappa_high = kappa_high ;
150 p->maxiter = maxiter ;
153 p->smooth_x = smooth_x ;
154 p->smooth_y = smooth_y ;
157 p->filter_size_x = 0 ;
158 p->filter_size_y = 0 ;
161 p->method = HDRL_BPM_2D_FILTERSMOOTH ;
167 return (hdrl_parameter *)p;
202 hdrl_bpm_2d_parameter * p = (hdrl_bpm_2d_parameter *)
203 hdrl_parameter_new(&hdrl_bpm_2d_parameter_type);
204 p->kappa_low = kappa_low ;
205 p->kappa_high = kappa_high ;
206 p->maxiter = maxiter ;
207 p->filter = CPL_FILTER_MEDIAN ;
208 p->border = CPL_BORDER_FILTER ;
211 p->steps_x = steps_x ;
212 p->steps_y = steps_y ;
213 p->filter_size_x = filter_size_x ;
214 p->filter_size_y = filter_size_y ;
215 p->order_x = order_x ;
216 p->order_y = order_y ;
217 p->method = HDRL_BPM_2D_LEGENDRESMOOTH ;
222 return (hdrl_parameter *)p;
233 const hdrl_parameter * param)
235 const hdrl_bpm_2d_parameter * param_loc = (
const hdrl_bpm_2d_parameter *)param ;
237 cpl_error_ensure(param != NULL, CPL_ERROR_NULL_INPUT,
238 return CPL_ERROR_NULL_INPUT,
"NULL Input Parameters");
240 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
241 "Expected BPM_2d parameter") ;
243 cpl_error_ensure(param_loc->method == HDRL_BPM_2D_LEGENDRESMOOTH ||
244 param_loc->method == HDRL_BPM_2D_FILTERSMOOTH,
245 CPL_ERROR_ILLEGAL_INPUT,
return CPL_ERROR_ILLEGAL_INPUT,
246 "Unsupported method");
248 switch (param_loc->method) {
249 case HDRL_BPM_2D_FILTERSMOOTH:
250 cpl_error_ensure(param_loc->smooth_x >= 0, CPL_ERROR_ILLEGAL_INPUT,
251 return CPL_ERROR_ILLEGAL_INPUT,
"smooth-x must be >=0");
252 cpl_error_ensure(param_loc->smooth_y >= 0, CPL_ERROR_ILLEGAL_INPUT,
253 return CPL_ERROR_ILLEGAL_INPUT,
"smooth-y must be >=0");
255 cpl_error_ensure(((param_loc->smooth_x)&1) == 1, CPL_ERROR_ILLEGAL_INPUT,
256 return CPL_ERROR_ILLEGAL_INPUT,
"smooth-x must be odd");
257 cpl_error_ensure(((param_loc->smooth_y)&1) == 1, CPL_ERROR_ILLEGAL_INPUT,
258 return CPL_ERROR_ILLEGAL_INPUT,
"smooth-y must be odd");
259 if (param_loc->filter != CPL_FILTER_AVERAGE &&
260 param_loc->filter != CPL_FILTER_AVERAGE_FAST &&
261 param_loc->filter != CPL_FILTER_MEDIAN) {
262 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
263 "Function only supports filters: "
264 "CPL_FILTER_AVERAGE, CPL_FILTER_AVERAGE_FAST "
265 "and CPL_FILTER_MEDIAN");
266 return CPL_ERROR_ILLEGAL_INPUT;
269 case HDRL_BPM_2D_LEGENDRESMOOTH:
270 cpl_error_ensure(param_loc->order_x >= 0, CPL_ERROR_ILLEGAL_INPUT,
271 return CPL_ERROR_ILLEGAL_INPUT,
"order-x must be >= 0");
272 cpl_error_ensure(param_loc->order_y >= 0, CPL_ERROR_ILLEGAL_INPUT,
273 return CPL_ERROR_ILLEGAL_INPUT,
"order-y must be >= 0");
274 cpl_error_ensure(param_loc->steps_x > param_loc->order_x, CPL_ERROR_ILLEGAL_INPUT,
275 return CPL_ERROR_ILLEGAL_INPUT,
"stepx_x must be > order-x");
276 cpl_error_ensure(param_loc->steps_y > param_loc->order_y, CPL_ERROR_ILLEGAL_INPUT,
277 return CPL_ERROR_ILLEGAL_INPUT,
"stepx_y must be > order-y");
278 cpl_error_ensure(param_loc->filter_size_x > 0, CPL_ERROR_ILLEGAL_INPUT,
279 return CPL_ERROR_ILLEGAL_INPUT,
"filter-size-x must be > 0");
280 cpl_error_ensure(param_loc->filter_size_y > 0, CPL_ERROR_ILLEGAL_INPUT,
281 return CPL_ERROR_ILLEGAL_INPUT,
"filter-size-y must be > 0");
285 cpl_error_ensure(param_loc->kappa_low >= 0, CPL_ERROR_ILLEGAL_INPUT,
286 return CPL_ERROR_ILLEGAL_INPUT,
"kappa-low must be >=0");
287 cpl_error_ensure(param_loc->kappa_high >= 0, CPL_ERROR_ILLEGAL_INPUT,
288 return CPL_ERROR_ILLEGAL_INPUT,
"kappa-high must be >=0");
289 cpl_error_ensure(param_loc->maxiter >= 0, CPL_ERROR_ILLEGAL_INPUT,
290 return CPL_ERROR_ILLEGAL_INPUT,
"maxiter must be >=0");
291 return CPL_ERROR_NONE ;
303 return hdrl_parameter_check_type(self, &hdrl_bpm_2d_parameter_type);
314 const hdrl_parameter * p)
316 cpl_ensure(p, CPL_ERROR_NULL_INPUT, CPL_FILTER_EROSION);
317 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->filter : CPL_FILTER_EROSION;
328 const hdrl_parameter * p)
330 cpl_ensure(p, CPL_ERROR_NULL_INPUT, CPL_BORDER_FILTER);
331 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->border : CPL_BORDER_FILTER;
342 const hdrl_parameter * p)
344 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1.0);
345 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->kappa_low : 0.;
356 const hdrl_parameter * p)
358 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1.0);
359 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->kappa_high : 0.;
370 const hdrl_parameter * p)
372 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1);
373 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->maxiter : 0;
384 const hdrl_parameter * p)
386 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1);
387 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->steps_x : 0;
398 const hdrl_parameter * p)
400 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1);
401 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->steps_y : 0;
412 const hdrl_parameter * p)
414 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1);
415 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->filter_size_x : 0;
426 const hdrl_parameter * p)
428 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1);
429 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->filter_size_y : 0;
440 const hdrl_parameter * p)
442 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1);
443 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->order_x : 0;
454 const hdrl_parameter * p)
456 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1);
457 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->order_y : 0;
468 const hdrl_parameter * p)
470 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1);
471 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->smooth_y : 0;
482 const hdrl_parameter * p)
484 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1);
485 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->smooth_x : 0;
496 const hdrl_parameter * p)
498 cpl_ensure(p, CPL_ERROR_NULL_INPUT, HDRL_BPM_2D_LEGENDRESMOOTH);
499 return p != NULL ? ((
const hdrl_bpm_2d_parameter *)p)->method : HDRL_BPM_2D_LEGENDRESMOOTH;
523static cpl_parameterlist * hdrl_bpm_2d_legendresmooth_parameter_create_parlist(
524 const char *base_context,
526 const hdrl_parameter *deflt)
528 cpl_ensure(prefix && base_context && deflt,
529 CPL_ERROR_NULL_INPUT, NULL);
532 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
534 cpl_parameterlist * parlist = cpl_parameterlist_new();
543 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"kappa-low", base_context,
544 "Low RMS scaling factor for image thresholding", CPL_TYPE_DOUBLE,
548 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"kappa-high", base_context,
549 "High RMS scaling factor for image thresholding", CPL_TYPE_DOUBLE,
553 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"maxiter", base_context,
554 "Maximum number of algorithm iterations", CPL_TYPE_INT, maxiter_def);
557 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"steps-x",
558 base_context,
"Number of image sampling points in x-dir for fitting",
562 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"steps-y",
563 base_context,
"Number of image sampling points in y-dir for fitting",
567 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"filter-size-x",
568 base_context,
"X size of the median box around sampling points", CPL_TYPE_INT,
572 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"filter-size-y",
573 base_context,
"Y size of the median box around sampling points", CPL_TYPE_INT,
577 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"order-x",
578 base_context,
"Order of x polynomial for the fit", CPL_TYPE_INT,
582 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"order-y",
583 base_context,
"Order of y polynomial for the fit", CPL_TYPE_INT,
588 if (cpl_error_get_code()) {
589 cpl_parameterlist_delete(parlist);
596static const char * filter_to_string(cpl_filter_mode filter)
599 case CPL_FILTER_EROSION:
602 case CPL_FILTER_DILATION:
605 case CPL_FILTER_OPENING:
608 case CPL_FILTER_CLOSING:
611 case CPL_FILTER_LINEAR:
614 case CPL_FILTER_LINEAR_SCALE:
615 return "LINEAR_SCALE";
617 case CPL_FILTER_AVERAGE:
620 case CPL_FILTER_AVERAGE_FAST:
621 return "AVERAGE_FAST";
623 case CPL_FILTER_MEDIAN:
626 case CPL_FILTER_STDEV:
629 case CPL_FILTER_STDEV_FAST:
632 case CPL_FILTER_MORPHO:
635 case CPL_FILTER_MORPHO_SCALE:
636 return "MORPHO_SCALE";
639 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
"Filter unknown");
645static const char * border_to_string(cpl_border_mode border)
648 case CPL_BORDER_FILTER:
651 case CPL_BORDER_ZERO:
654 case CPL_BORDER_CROP:
660 case CPL_BORDER_COPY:
664 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
"border unknown");
689static cpl_parameterlist * hdrl_bpm_2d_filtersmooth_parameter_create_parlist(
690 const char *base_context,
692 const hdrl_parameter *deflt)
694 cpl_ensure(prefix && base_context && deflt,
695 CPL_ERROR_NULL_INPUT, NULL);
698 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
701 cpl_parameterlist * parlist = cpl_parameterlist_new();
702 cpl_parameter * par ;
711 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"kappa-low", base_context,
712 "Low RMS scaling factor for image thresholding", CPL_TYPE_DOUBLE, kappa_low_def) ;
715 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"kappa-high", base_context,
716 "High RMS scaling factor for image thresholding", CPL_TYPE_DOUBLE, kappa_high_def) ;
719 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"maxiter", base_context,
720 "Maximum number of algorithm iterations", CPL_TYPE_INT, maxiter_def);
724 const char * filter_def = filter_to_string(filter);
726 par = cpl_parameter_new_enum(name, CPL_TYPE_STRING,
"Filter mode for image smooting",
727 context, filter_def, 3,
"AVERAGE",
"AVERAGE_FAST",
"MEDIAN");
730 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, name);
731 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
733 cpl_parameterlist_append(parlist, par);
737 const char * border_def = border_to_string(border);
739 par = cpl_parameter_new_enum(name, CPL_TYPE_STRING,
740 "Border mode to use for the image smooting filter "
741 "(only for MEDIAN filter)",
742 context, border_def, 4,
"FILTER",
"CROP",
"NOP",
"COPY");
745 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, name);
746 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
748 cpl_parameterlist_append(parlist, par);
751 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"smooth-x",
752 base_context,
"Kernel y size of the smoothing filter", CPL_TYPE_INT,
756 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"smooth-y",
757 base_context,
"Kernel y size of the image smoothing filter", CPL_TYPE_INT,
761 if (cpl_error_get_code()) {
762 cpl_parameterlist_delete(parlist);
799 const char *base_context,
801 const char *method_def,
802 const hdrl_parameter *filtersmooth_def,
803 const hdrl_parameter *legendresmooth_def)
805 cpl_ensure(prefix && base_context && method_def,
806 CPL_ERROR_NULL_INPUT, NULL);
808 cpl_ensure(filtersmooth_def || legendresmooth_def,
809 CPL_ERROR_NULL_INPUT, NULL);
811 if(filtersmooth_def){
813 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
816 if(legendresmooth_def){
818 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
822 cpl_parameterlist * parlist = cpl_parameterlist_new();
823 cpl_parameter * par ;
829 par = cpl_parameter_new_enum(name, CPL_TYPE_STRING,
"Method used", context,
830 method_def, 2,
"FILTER",
"LEGENDRE");
833 cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI, name);
835 cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
836 cpl_parameterlist_append(parlist, par);
840 cpl_parameterlist * pleg = hdrl_bpm_2d_legendresmooth_parameter_create_parlist(
841 base_context, name, legendresmooth_def);
843 for (cpl_parameter * p = cpl_parameterlist_get_first(pleg) ;
844 p != NULL; p = cpl_parameterlist_get_next(pleg))
845 cpl_parameterlist_append(parlist, cpl_parameter_duplicate(p));
846 cpl_parameterlist_delete(pleg);
850 cpl_parameterlist * pfil = hdrl_bpm_2d_filtersmooth_parameter_create_parlist(
851 base_context, name, filtersmooth_def);
853 for (cpl_parameter * p = cpl_parameterlist_get_first(pfil) ;
854 p != NULL; p = cpl_parameterlist_get_next(pfil))
855 cpl_parameterlist_append(parlist, cpl_parameter_duplicate(p));
856 cpl_parameterlist_delete(pfil);
859 if (cpl_error_get_code()) {
860 cpl_parameterlist_delete(parlist);
897 const cpl_parameterlist * parlist,
900 cpl_ensure(prefix && parlist, CPL_ERROR_NULL_INPUT, NULL);
902 const cpl_parameter * par;
903 const char * tmp_str;
904 cpl_filter_mode filter = CPL_FILTER_EROSION ;
905 cpl_border_mode border = CPL_BORDER_FILTER ;
906 double kappa_low = -1.0 ;
907 double kappa_high = -1.0 ;
911 int filter_size_x = -1 ;
912 int filter_size_y = -1 ;
915 cpl_size smooth_x = -1 ;
916 cpl_size smooth_y = -1 ;
917 hdrl_bpm_2d_method method ;
921 par = cpl_parameterlist_find_const(parlist, name) ;
922 tmp_str = cpl_parameter_get_string(par);
923 if (tmp_str == NULL) {
924 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
925 "Parameter %s not found", name);
930 if(!strcmp(tmp_str,
"FILTER")) {
931 method = HDRL_BPM_2D_FILTERSMOOTH ;
932 }
else if(!strcmp(tmp_str,
"LEGENDRE")) {
933 method = HDRL_BPM_2D_LEGENDRESMOOTH ;
935 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
936 "Invalid method: %s", tmp_str);
941 method == HDRL_BPM_2D_FILTERSMOOTH ?
942 "filter" :
"legendre" );
946 par=cpl_parameterlist_find_const(parlist, name);
947 kappa_low = cpl_parameter_get_double(par);
952 par=cpl_parameterlist_find_const(parlist, name);
953 kappa_high = cpl_parameter_get_double(par);
958 par=cpl_parameterlist_find_const(parlist, name);
959 maxiter = cpl_parameter_get_int(par);
962 cpl_free(kappa_prefix);
966 par=cpl_parameterlist_find_const(parlist, name);
967 steps_x = cpl_parameter_get_int(par);
972 par=cpl_parameterlist_find_const(parlist, name);
973 steps_y = cpl_parameter_get_int(par);
978 par=cpl_parameterlist_find_const(parlist, name);
979 filter_size_x = cpl_parameter_get_int(par);
984 par=cpl_parameterlist_find_const(parlist, name);
985 filter_size_y = cpl_parameter_get_int(par);
990 par=cpl_parameterlist_find_const(parlist, name);
991 order_x = cpl_parameter_get_int(par);
996 par=cpl_parameterlist_find_const(parlist, name);
997 order_y = cpl_parameter_get_int(par);
1002 par = cpl_parameterlist_find_const(parlist, name) ;
1003 tmp_str = cpl_parameter_get_string(par);
1004 if (tmp_str == NULL) {
1005 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1006 "Parameter %s not found", name);
1010 if(!strcmp(tmp_str,
"erosion")) {
1011 filter = CPL_FILTER_EROSION ;
1012 }
else if(!strcmp(tmp_str,
"DILATION")) {
1013 filter = CPL_FILTER_DILATION ;
1014 }
else if(!strcmp(tmp_str,
"OPENING")) {
1015 filter = CPL_FILTER_OPENING ;
1016 }
else if(!strcmp(tmp_str,
"CLOSING")) {
1017 filter = CPL_FILTER_CLOSING ;
1018 }
else if(!strcmp(tmp_str,
"LINEAR")) {
1019 filter = CPL_FILTER_LINEAR ;
1020 }
else if(!strcmp(tmp_str,
"LINEAR_SCALE")) {
1021 filter = CPL_FILTER_LINEAR_SCALE ;
1022 }
else if(!strcmp(tmp_str,
"AVERAGE")) {
1023 filter = CPL_FILTER_AVERAGE ;
1024 }
else if(!strcmp(tmp_str,
"AVERAGE_FAST")) {
1025 filter = CPL_FILTER_AVERAGE_FAST ;
1026 }
else if(!strcmp(tmp_str,
"MEDIAN")) {
1027 filter = CPL_FILTER_MEDIAN ;
1028 }
else if(!strcmp(tmp_str,
"STDEV")) {
1029 filter = CPL_FILTER_STDEV ;
1030 }
else if(!strcmp(tmp_str,
"STDEV_FAST")) {
1031 filter = CPL_FILTER_STDEV_FAST ;
1032 }
else if(!strcmp(tmp_str,
"MORPHO")) {
1033 filter = CPL_FILTER_MORPHO ;
1034 }
else if(!strcmp(tmp_str,
"MORPHO_SCALE")) {
1035 filter = CPL_FILTER_MORPHO_SCALE ;
1041 par = cpl_parameterlist_find_const(parlist, name) ;
1042 tmp_str = cpl_parameter_get_string(par);
1043 if (tmp_str == NULL) {
1044 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1045 "Parameter %s not found", name);
1049 if(!strcmp(tmp_str,
"filter")) {
1050 border = CPL_BORDER_FILTER ;
1051 }
else if(!strcmp(tmp_str,
"ZERO")) {
1052 border = CPL_BORDER_ZERO ;
1053 }
else if(!strcmp(tmp_str,
"CROP")) {
1054 border = CPL_BORDER_CROP ;
1055 }
else if(!strcmp(tmp_str,
"NOP")) {
1056 border = CPL_BORDER_NOP ;
1057 }
else if(!strcmp(tmp_str,
"COPY")) {
1058 border = CPL_BORDER_COPY ;
1064 par=cpl_parameterlist_find_const(parlist, name);
1065 smooth_x = cpl_parameter_get_int(par);
1070 par=cpl_parameterlist_find_const(parlist, name);
1071 smooth_y = cpl_parameter_get_int(par);
1075 if (cpl_error_get_code()) {
1076 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1077 "Error while parsing parameterlist with prefix %s", prefix);
1080 if (method == HDRL_BPM_2D_FILTERSMOOTH) {
1082 kappa_high, maxiter, filter, border, smooth_x, smooth_y) ;
1083 }
else if (method == HDRL_BPM_2D_LEGENDRESMOOTH) {
1085 kappa_high, maxiter, steps_x, steps_y, filter_size_x,
1086 filter_size_y, order_x, order_y) ;
1137 const hdrl_image * img_in,
1138 const hdrl_parameter * params)
1141 cpl_mask * mask_iter, * img_mask;
1144 cpl_error_ensure(img_in && params, CPL_ERROR_NULL_INPUT,
1145 return NULL,
"NULL input");
1149 const hdrl_bpm_2d_parameter * p_loc = (
const hdrl_bpm_2d_parameter *)params ;
1152 img_mask = cpl_mask_duplicate(cpl_image_get_bpm(img));
1155 mask_iter = cpl_mask_duplicate(img_mask);
1158 for (
int var = 0; var < p_loc->maxiter; ++var) {
1159 cpl_image * img_res = NULL;
1160 cpl_mask * mask_iter_startloop = cpl_mask_duplicate(mask_iter);
1161 double median, mad, std_mad, std_mad_low, std_mad_high ;
1164 cpl_mask_or(mask_iter, img_mask);
1167 if (p_loc->method == HDRL_BPM_2D_FILTERSMOOTH){
1168 img_res = hdrl_get_residuals_filtersmooth(p_loc->smooth_x,
1169 p_loc->smooth_y, p_loc->filter, p_loc->border, img,
1171 }
else if (p_loc->method == HDRL_BPM_2D_LEGENDRESMOOTH) {
1172 img_res = hdrl_get_residuals_legendresmooth(img, p_loc->steps_x,
1173 p_loc->steps_y, p_loc->filter_size_x, p_loc->filter_size_y,
1174 p_loc->order_x, p_loc->order_y);
1187 median = cpl_image_get_mad(img_res, &mad);
1190 mad=nextafter(0,1.0);
1192 std_mad = CPL_MATH_STD_MAD * mad;
1193 std_mad_low = median -(std_mad * p_loc->kappa_low);
1194 std_mad_high = median + (std_mad * p_loc->kappa_high);
1199 cpl_image_reject_from_mask(img_res, img_mask);
1203 cpl_mask_xor(mask_iter, mask_iter);
1205 cpl_mask_threshold_image(mask_iter, img_res, std_mad_low, std_mad_high,
1211 cpl_mask_xor(mask_iter, img_mask);
1212 cpl_image_delete(img_res);
1214 if (!hdrl_check_maskequality(mask_iter, mask_iter_startloop)) {
1215 cpl_mask_delete(mask_iter_startloop);
1216 cpl_msg_debug(cpl_func,
"iter: %d", var);
1219 cpl_mask_delete(mask_iter_startloop);
1220 cpl_msg_debug(cpl_func,
"iter: %d", var);
1222 cpl_mask_delete(img_mask);
1223 cpl_image_delete(img);
1248static cpl_image * hdrl_get_residuals_legendresmooth(
1249 const cpl_image * img,
1257 cpl_image * img_res;
1258 cpl_image * img_filtered;
1259 cpl_size nx = cpl_image_get_size_x(img);
1260 cpl_size ny = cpl_image_get_size_y(img);
1261 cpl_size sx = CX_MAX(nx / steps_x, 1);
1262 cpl_size sy = CX_MAX(ny / steps_y, 1);
1265 cpl_matrix * x = hdrl_matrix_linspace(sx / 2, nx, sx);
1266 cpl_matrix * y = hdrl_matrix_linspace(sy / 2, ny, sy);
1267 cpl_image * imgtmp_mod =
1268 hdrl_medianfilter_image_grid(img, x, y,
1271 cpl_matrix * coeffs = hdrl_fit_legendre(imgtmp_mod,
1275 img_filtered = hdrl_legendre_to_image(coeffs, order_x, order_y, nx, ny);
1276 img_res = cpl_image_subtract_create(img, img_filtered);
1277 if (cpl_msg_get_level() == CPL_MSG_DEBUG)
1278 cpl_matrix_dump(coeffs, stdout);
1279 cpl_matrix_delete(coeffs);
1280 cpl_matrix_delete(x);
1281 cpl_matrix_delete(y);
1282 cpl_image_delete(imgtmp_mod);
1283 cpl_image_delete(img_filtered);
1299static cpl_image * hdrl_get_residuals_filtersmooth(
1300 cpl_size kernel_size_x,
1301 cpl_size kernel_size_y,
1302 cpl_filter_mode filter,
1303 cpl_border_mode border,
1305 cpl_mask * mask_iter)
1308 cpl_image * img_res = NULL;
1309 cpl_image * img_filtered = NULL;
1311 cpl_size nx = cpl_image_get_size_x(img);
1312 cpl_size ny = cpl_image_get_size_y(img);
1316 kernel = cpl_mask_new(kernel_size_x, kernel_size_y) ;
1317 cpl_mask_not(kernel);
1318 if (kernel == NULL)
return NULL ;
1321 cpl_image_reject_from_mask(img, mask_iter);
1322 if (border == CPL_BORDER_FILTER) {
1323 img_filtered = hdrl_parallel_filter_image(img, NULL, kernel, filter);
1326 img_filtered = cpl_image_new(nx, ny, HDRL_TYPE_DATA);
1327 cpl_image_filter_mask(img_filtered, img, kernel, filter, border);
1329 cpl_mask_delete(kernel) ;
1330 img_res = cpl_image_subtract_create(img, img_filtered);
1331 cpl_image_delete(img_filtered);
cpl_mask * hdrl_bpm_2d_compute(const hdrl_image *img_in, const hdrl_parameter *params)
Detect bad pixels on a single image with an iterative process.
hdrl_bpm_2d_method hdrl_bpm_2d_parameter_get_method(const hdrl_parameter *p)
Access the method in the BPM_2D parameter.
double hdrl_bpm_2d_parameter_get_kappa_high(const hdrl_parameter *p)
Access the kappa_high in the BPM_2D parameter.
int hdrl_bpm_2d_parameter_get_maxiter(const hdrl_parameter *p)
Access the maxiter in the BPM_2D parameter.
cpl_border_mode hdrl_bpm_2d_parameter_get_border(const hdrl_parameter *p)
Access the border in the BPM_2D parameter.
int hdrl_bpm_2d_parameter_get_filter_size_y(const hdrl_parameter *p)
Access the filter_size_y in the BPM_2D parameter.
int hdrl_bpm_2d_parameter_get_smooth_y(const hdrl_parameter *p)
Access the smooth_y in the BPM_2D parameter.
int hdrl_bpm_2d_parameter_get_order_y(const hdrl_parameter *p)
Access the order_y in the BPM_2D parameter.
hdrl_parameter * hdrl_bpm_2d_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse parameter list to create input parameters for the BPM_2D.
int hdrl_bpm_2d_parameter_get_filter_size_x(const hdrl_parameter *p)
Access the filter_size_x in the BPM_2D parameter.
hdrl_parameter * hdrl_bpm_2d_parameter_create_filtersmooth(double kappa_low, double kappa_high, int maxiter, cpl_filter_mode filter, cpl_border_mode border, int smooth_x, int smooth_y)
Creates BPM_2D Parameters object for HDRL_BPM_2D_FILTERSMOOTH.
int hdrl_bpm_2d_parameter_get_smooth_x(const hdrl_parameter *p)
Access the smooth_x in the BPM_2D parameter.
int hdrl_bpm_2d_parameter_get_steps_x(const hdrl_parameter *p)
Access the steps_x in the BPM_2D parameter.
cpl_filter_mode hdrl_bpm_2d_parameter_get_filter(const hdrl_parameter *p)
Access the filter in the BPM_2D parameter.
cpl_error_code hdrl_bpm_2d_parameter_verify(const hdrl_parameter *param)
Verify basic correctness of the BPM_2D parameters.
cpl_parameterlist * hdrl_bpm_2d_parameter_create_parlist(const char *base_context, const char *prefix, const char *method_def, const hdrl_parameter *filtersmooth_def, const hdrl_parameter *legendresmooth_def)
Create parameter list for the BPM_2D computation.
int hdrl_bpm_2d_parameter_get_order_x(const hdrl_parameter *p)
Access the order_x in the BPM_2D parameter.
int hdrl_bpm_2d_parameter_get_steps_y(const hdrl_parameter *p)
Access the steps_y in the BPM_2D parameter.
hdrl_parameter * hdrl_bpm_2d_parameter_create_legendresmooth(double kappa_low, double kappa_high, int maxiter, int steps_x, int steps_y, int filter_size_x, int filter_size_y, int order_x, int order_y)
Creates BPM_2D Parameters object for HDRL_BPM_2D_LEGENDRESMOOTH.
cpl_boolean hdrl_bpm_2d_parameter_check(const hdrl_parameter *self)
Check that the parameter is a BPM_2D parameter.
double hdrl_bpm_2d_parameter_get_kappa_low(const hdrl_parameter *p)
Access the kappa_low in the BPM_2D parameter.
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
char * hdrl_join_string(const char *sep_, int n,...)
join strings together