28#include "hdrl_types.h"
29#include "hdrl_image.h"
30#include "hdrl_imagelist.h"
31#include "hdrl_utils.h"
33#include "hdrl_bpm_fit.h"
70double igamc(
double,
double);
83} hdrl_bpm_fit_parameter;
86static hdrl_parameter_typeobj hdrl_bpm_fit_parameter_type = {
87 HDRL_PARAMETER_BPM_FIT,
88 (hdrl_alloc *)&cpl_malloc,
89 (hdrl_free *)&cpl_free,
91 sizeof(hdrl_bpm_fit_parameter),
107static hdrl_parameter *
108hdrl_bpm_fit_parameter_create_all(
int degree,
double pval,
109 double rel_chi_l,
double rel_chi_h,
110 double rel_coef_l,
double rel_coef_h)
112 hdrl_bpm_fit_parameter * p = (hdrl_bpm_fit_parameter *)
113 hdrl_parameter_new(&hdrl_bpm_fit_parameter_type);
116 p->rel_chi_l = rel_chi_l;
117 p->rel_chi_h = rel_chi_h;
118 p->rel_coef_l = rel_coef_l;
119 p->rel_coef_h = rel_coef_h;
122 return (hdrl_parameter *)p;
144 return hdrl_bpm_fit_parameter_create_all(degree, pval, -1, -1, -1, -1);
159 double rel_chi_low,
double rel_chi_high)
161 return hdrl_bpm_fit_parameter_create_all(degree, -1,
162 rel_chi_low, rel_chi_high, -1, -1);
177 double rel_coef_low,
double rel_coef_high)
179 return hdrl_bpm_fit_parameter_create_all(degree, -1,
180 -1, -1, rel_coef_low, rel_coef_high);
192 return hdrl_parameter_check_type(self, &hdrl_bpm_fit_parameter_type);
204 cpl_ensure(p, CPL_ERROR_NULL_INPUT, 0);
206 CPL_ERROR_INCOMPATIBLE_INPUT, 0);
207 const hdrl_bpm_fit_parameter * par = (
const hdrl_bpm_fit_parameter *)p;
209 if (par->degree < 0) {
210 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
211 "degree must be positive");
214 if (par->pval >= 0) {
215 if (par->pval > 100.) {
216 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
217 "pval must be between 0 and 100%%");
222 if (par->rel_chi_l >= 0 || par->rel_chi_h >= 0) {
224 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
225 "Only one rejection criteria is allowed, "
226 "set the others to negative values");
228 if (!(par->rel_chi_l >= 0 && par->rel_chi_h >= 0)) {
229 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
230 "Upper and lower rejection criteria must be >= 0");
235 if (par->rel_coef_l >= 0 || par->rel_coef_h >= 0) {
237 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
238 "Only one rejection criteria is allowed, "
239 "set the others to negative values");
241 if (!(par->rel_coef_l >= 0 && par->rel_coef_h >= 0)) {
242 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
243 "Upper and lower rejection criteria must be >= 0");
249 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
250 "Only no bad pixel parameter given, the chosen threshold "
251 "must have a value larger than zero");
253 return CPL_ERROR_NONE;
265 cpl_ensure(p, CPL_ERROR_NULL_INPUT, 0);
267 CPL_ERROR_INCOMPATIBLE_INPUT, 0);
268 return ((
const hdrl_bpm_fit_parameter *)p)->degree;
280 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1.);
282 CPL_ERROR_INCOMPATIBLE_INPUT, -1.);
283 return ((
const hdrl_bpm_fit_parameter *)p)->pval;
295 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1.);
297 CPL_ERROR_INCOMPATIBLE_INPUT, -1.);
298 return ((
const hdrl_bpm_fit_parameter *)p)->rel_chi_l;
310 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1.);
312 CPL_ERROR_INCOMPATIBLE_INPUT, -1.);
313 return ((
const hdrl_bpm_fit_parameter *)p)->rel_chi_h;
325 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1.);
327 CPL_ERROR_INCOMPATIBLE_INPUT, -1.);
328 return ((
const hdrl_bpm_fit_parameter *)p)->rel_coef_l;
340 cpl_ensure(p, CPL_ERROR_NULL_INPUT, -1.);
342 CPL_ERROR_INCOMPATIBLE_INPUT, -1.);
343 return ((
const hdrl_bpm_fit_parameter *)p)->rel_coef_h;
364 const char *base_context,
366 const hdrl_parameter *defaults)
368 cpl_ensure(prefix && base_context && defaults,
369 CPL_ERROR_NULL_INPUT, NULL);
372 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
374 cpl_parameterlist *parlist = cpl_parameterlist_new();
378 double rel_chi_low_default =
380 double rel_chi_high_default =
382 double rel_coef_low_default =
384 double rel_coef_high_default =
387 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"degree", base_context,
388 "Degree of polynomial to fit.", CPL_TYPE_INT, degree_default);
390 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"pval", base_context,
391 "p-value threshold (in percent). Fits with a p-value below "
392 "this threshold are considered bad pixels.",
393 CPL_TYPE_DOUBLE, pval_default);
395 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"rel-chi-low", base_context,
396 "Relative chi threshold. Pixels with with a chi value "
397 "smaller than mean - rel-threshold * stdev-of-chi are "
398 "considered bad pixels.", CPL_TYPE_DOUBLE, rel_chi_low_default);
400 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"rel-chi-high", base_context,
401 "Relative chi threshold. Pixels with with a chi value larger "
402 "than mean + rel-threshold * stdev-of-chi are "
403 "considered bad pixels.", CPL_TYPE_DOUBLE, rel_chi_high_default);
405 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"rel-coef-low", base_context,
406 "Relative fit coefficient threshold. Pixels with with a "
407 "coefficient value smaller than "
408 "mean +- rel-threshold * stdev-of-coeff are "
409 "considered bad pixels.", CPL_TYPE_DOUBLE, rel_coef_low_default);
411 hdrl_setup_vparameter(parlist, prefix,
".",
"",
"rel-coef-high", base_context,
412 "Relative fit coefficient threshold. Pixels with with a "
413 "coefficient value larger than "
414 "mean +- rel-threshold * stdev-of-coeff are "
415 "considered bad pixels.", CPL_TYPE_DOUBLE, rel_coef_high_default);
417 if (cpl_error_get_code()) {
418 cpl_parameterlist_delete(parlist);
443 const cpl_parameterlist * parlist,
446 cpl_ensure(prefix && parlist, CPL_ERROR_NULL_INPUT, NULL);
448 const cpl_parameter * par;
450 double rel_chi_l = -1;
451 double rel_chi_h = -1;
452 double rel_coef_l = -1;
453 double rel_coef_h = -1;
457 par = cpl_parameterlist_find_const(parlist, name);
459 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
460 "Parameter %s not found", name);
464 degree = cpl_parameter_get_int(par);
468 par = cpl_parameterlist_find_const(parlist, name);
470 pval = cpl_parameter_get_double(par);
475 par = cpl_parameterlist_find_const(parlist, name);
477 rel_chi_l = cpl_parameter_get_double(par);
482 par = cpl_parameterlist_find_const(parlist, name);
484 rel_chi_h = cpl_parameter_get_double(par);
489 par = cpl_parameterlist_find_const(parlist, name);
491 rel_coef_l = cpl_parameter_get_double(par);
496 par = cpl_parameterlist_find_const(parlist, name);
498 rel_coef_h = cpl_parameter_get_double(par);
502 if (cpl_error_get_code()) {
506 return hdrl_bpm_fit_parameter_create_all(degree, pval,
507 rel_chi_l, rel_chi_h, rel_coef_l, rel_coef_h);
522bpm_from_rel(cpl_image * img,
double kappa_low,
double kappa_high,
int mad)
527 m = cpl_image_get_mad(img, &s);
528 s *= CPL_MATH_STD_MAD;
529 s = CX_MAX(DBL_EPSILON, s);
532 m = cpl_image_get_mean(img);
533 s = cpl_image_get_stdev(img);
535 cpl_mask * bpm = cpl_mask_threshold_image_create(img, m - s * kappa_low,
538 r = cpl_image_new_from_mask(bpm);
539 cpl_mask_delete(bpm);
588 const hdrl_imagelist * data,
589 const cpl_vector * sample_pos,
590 cpl_image ** out_mask)
592 cpl_image * out_chi2 = NULL, * out_dof = NULL;
593 hdrl_imagelist * out_coef = NULL;
595 return cpl_error_get_code();
603 &out_coef, &out_chi2, &out_dof);
605 return cpl_error_set_message(cpl_func, CPL_ERROR_FILE_NOT_FOUND,
609 if (cpl_image_count_rejected(out_chi2) ==
610 (cpl_image_get_size_x(out_chi2) * cpl_image_get_size_y(out_chi2))) {
611 cpl_msg_error(cpl_func,
"Too few good pixels to fit polynomial of "
612 "degree %d in all pixels", degree);
617 cpl_image * bpm = NULL;
624 if (rel_chi_l >= 0) {
626 cpl_image_power(out_chi2, 0.5);
627 bpm = bpm_from_rel(out_chi2, rel_chi_l, rel_chi_h, 1);
629 else if (rel_coef_l >= 0) {
633 rel_coef_l, rel_coef_h, 0);
637 cpl_image_multiply_scalar(b, pow(2, i));
638 cpl_image_add(bpm, b);
646 else if (pval >= 0) {
648 bpm = cpl_image_new(cpl_image_get_size_x(out_chi2),
649 cpl_image_get_size_y(out_chi2),
651 int * md = cpl_image_get_data_int(bpm);
652 hdrl_data_t * cd = cpl_image_get_data(out_chi2);
653 hdrl_data_t * dd = cpl_image_get_data(out_dof);
654 for (
size_t i = 0; i < (size_t)cpl_image_get_size_x(out_chi2) *
655 cpl_image_get_size_y(out_chi2); i++) {
656 double pv = igamc(dd[i] / 2., cd[i] / 2.);
665 cpl_image_delete(out_chi2);
666 cpl_image_delete(out_dof);
668 return cpl_error_get_code();
hdrl_parameter * hdrl_bpm_fit_parameter_create_rel_coef(int degree, double rel_coef_low, double rel_coef_high)
create bpm_fit parameter with relative coefficient bpm treshold
hdrl_parameter * hdrl_bpm_fit_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse a parameterlist to create input parameters for the BPM_FIT.
double hdrl_bpm_fit_parameter_get_rel_chi_high(const hdrl_parameter *p)
get relative chi distribution upper threshold
double hdrl_bpm_fit_parameter_get_rel_coef_high(const hdrl_parameter *p)
get relative fit coefficient distribution upper threshold
int hdrl_bpm_fit_parameter_get_degree(const hdrl_parameter *p)
get degree of polynomial fit of parameter
cpl_error_code hdrl_bpm_fit_parameter_verify(const hdrl_parameter *p)
verify that the parameter is a valid bpm_fit_parameter
cpl_parameterlist * hdrl_bpm_fit_parameter_create_parlist(const char *base_context, const char *prefix, const hdrl_parameter *defaults)
Create a parameter list for the BPM_FIT computation.
hdrl_parameter * hdrl_bpm_fit_parameter_create_pval(int degree, double pval)
create bpm_fit parameter with p-value bpm treshold
double hdrl_bpm_fit_parameter_get_pval(const hdrl_parameter *p)
get p-value bpm treshold
double hdrl_bpm_fit_parameter_get_rel_chi_low(const hdrl_parameter *p)
get relative chi distribution lower threshold
hdrl_parameter * hdrl_bpm_fit_parameter_create_rel_chi(int degree, double rel_chi_low, double rel_chi_high)
create bpm_fit parameter with relative chi bpm treshold
cpl_boolean hdrl_bpm_fit_parameter_check(const hdrl_parameter *self)
Check that the parameter is a bpm_fit parameter.
double hdrl_bpm_fit_parameter_get_rel_coef_low(const hdrl_parameter *p)
get relative fit coefficient distribution lower threshold
cpl_error_code hdrl_bpm_fit_compute(const hdrl_parameter *par, const hdrl_imagelist *data, const cpl_vector *sample_pos, cpl_image **out_mask)
compute bad pixel map based on fitting a stack of images
cpl_error_code hdrl_fit_polynomial_imagelist(const hdrl_imagelist *list, const cpl_vector *samplepos, const int degree, hdrl_imagelist **coef, cpl_image **chi2, cpl_image **dof)
weighted least squares polynomial fit of each pixel of a imagelist
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter
char * hdrl_join_string(const char *sep_, int n,...)
join strings together