20#include "hdrl_cat_background.h"
22#include "hdrl_cat_filter.h"
23#include "hdrl_cat_utils_sort.h"
25#include "hdrl_image.h"
30static cpl_image * hdrl_sigclipfilter_image_grid(
31 const cpl_image *ima, cpl_matrix *x, cpl_matrix *y,
32 cpl_size filtersize_x, cpl_size filtersize_y);
34static cpl_matrix * matrix_linspace(cpl_size start, cpl_size stop, cpl_size step);
68 ap_t *ap, cpl_size nbsize, cpl_size bkg_subtr, hdrl_casu_result *res)
71 double *map = ap->indata;
72 cpl_size nx = ap->lsiz;
73 cpl_size ny = ap->csiz;
74 unsigned char *mflag = ap->mflag;
77 nbsize = CPL_MIN(CPL_MIN(nx, ny), nbsize);
79 double fracx = (double)nx / (
double)nbsize;
80 double fracy = (double)ny / (
double)nbsize;
82 cpl_size ifracx = (cpl_size)(fracx + 0.1);
83 cpl_size ifracy = (cpl_size)(fracy + 0.1);
85 cpl_size nbsizx = nx / ifracx;
86 cpl_size nbsizy = ny / ifracy;
89 double a = 0.9 * nbsize;
90 cpl_size aux = (cpl_size)(a + (a < 0 ? -0.5 : 0.5));
91 nbsize = CPL_MAX(aux, CPL_MIN(nbsize, CPL_MIN(nbsizx, nbsizy)));
92 nbsize = CPL_MIN( nx, CPL_MIN(ny, nbsize ));
95 cpl_size nbx = nx / nbsize;
96 cpl_size nby = ny / nbsize;
99 double **bvals = cpl_malloc(nby *
sizeof(
double *));
100 for (cpl_size l = 0; l < nby; l++) {
101 bvals[l] = cpl_malloc(nbx *
sizeof(
double));
105 ap->backmap.nbx = nbx;
106 ap->backmap.nby = nby;
107 ap->backmap.nbsize = nbsize;
108 ap->backmap.bvals = bvals;
111 cpl_image *image = cpl_image_wrap_double(nx, ny, map);
112 cpl_mask *image_mask = cpl_image_get_bpm(image);
113 cpl_binary *image_mask_data = cpl_mask_get_data(image_mask);
116 for (cpl_size i = 0; i < nx * ny ; i++){
117 if ( mflag[i] == MF_ZEROCONF
118 || mflag[i] == MF_STUPID_VALUE
119 || mflag[i] == MF_SATURATED )
121 image_mask_data[i] = CPL_BINARY_1;
126 cpl_size steps_x = nbx;
127 cpl_size steps_y = nby;
128 cpl_size sx = CPL_MAX(nx / steps_x, 1);
129 cpl_size sy = CPL_MAX(ny / steps_y, 1);
130 cpl_matrix *x = matrix_linspace(sx / 2, nx, sx);
131 cpl_matrix *y = matrix_linspace(sy / 2, ny, sy);
132 cpl_size filter_size_x = nbsize / 2;
133 cpl_size filter_size_y = nbsize / 2;
134 cpl_image *imgtmp_mod = hdrl_sigclipfilter_image_grid(image, x, y, filter_size_x, filter_size_y);
137 cpl_detector_interpolate_rejected(imgtmp_mod);
139 cpl_matrix_delete(x);
140 cpl_matrix_delete(y);
142 for (cpl_size l = 0; l < nby; l++) {
143 for (cpl_size j = 0; j < nbx; j++) {
145 bvals[l][j] = cpl_image_get(imgtmp_mod, j + 1, l + 1, &rej);
149 cpl_image_delete(imgtmp_mod);
150 cpl_image_unwrap(image);
156 double *work = cpl_malloc(nbx * nby *
sizeof(
double));
159 for (cpl_size l = 0; l < nby; l++) {
160 for (cpl_size j = 0; j < nbx; j++) {
161 work[k++] = bvals[l][j];
165 sort_array((
void *)work, k,
sizeof(*work), HDRL_SORT_DOUBLE, CPL_SORT_ASCENDING);
166 double avsky = work[(k) / 2];
170 cpl_size nbsizo2 = nbsize / 2;
171 double fnbsize = 1. / (double)nbsize;
172 for (k = 0; k < ny; k++) {
174 cpl_size kk = k * nx;
177 cpl_size iby = (k + 1 + nbsizo2) / nbsize;
178 cpl_size ibyp1 = iby + 1;
179 iby = CPL_MIN(nby, CPL_MAX(1, iby));
180 ibyp1 = CPL_MIN(nby, ibyp1);
182 double dely = (k + 1. - nbsize*iby + nbsizo2) * fnbsize;
184 for (cpl_size j = 0; j < nx; j++) {
187 cpl_size ibx = (j + 1 + nbsizo2) / nbsize;
188 cpl_size ibxp1 = ibx + 1;
189 ibx = CPL_MIN(nbx, CPL_MAX(1, ibx));
190 ibxp1 = CPL_MIN(nbx, ibxp1);
192 double delx = (j + 1. - nbsize * ibx + nbsizo2) * fnbsize;
195 double t1 = (1. - dely) * bvals[iby - 1][ibx - 1] + dely * bvals[ibyp1 - 1][ibx - 1];
196 double t2 = (1. - dely) * bvals[iby - 1][ibxp1 - 1] + dely * bvals[ibyp1 - 1][ibxp1 - 1];
197 double dsky = avsky - (1. - delx) * t1 - delx * t2;
204 if (res->background) {
205 cpl_image_set(res->background, j + 1, k + 1, avsky - dsky);
211 return CPL_ERROR_NONE;
231 ap_t *ap,
double *skymed,
double *skysig)
234 double *map = ap->indata;
235 cpl_size nx = ap->lsiz;
236 cpl_size ny = ap->csiz;
237 unsigned char *mflag = ap->mflag;
239 cpl_image *ima_wrp = cpl_image_wrap_double(nx, ny, map);
240 cpl_mask *image_mask = cpl_image_get_bpm(ima_wrp);
241 cpl_binary *image_mask_data = cpl_mask_get_data(image_mask);
244 for (cpl_size i = 0; i < nx * ny ; i++){
245 if ( mflag[i] == MF_ZEROCONF
246 || mflag[i] == MF_STUPID_VALUE
247 || mflag[i] == MF_SATURATED )
249 image_mask_data[i] = CPL_BINARY_1;
257 for (cpl_size i = 0; i < niter; i++ ) {
260 double median = cpl_image_get_mad(ima_wrp, &mad);
261 double stdev = mad * CPL_MATH_STD_MAD;
263 double kappa_low = 2.5;
264 double lo_cut = median - kappa_low * stdev;
266 double kappa_high = 2.5;
267 double hi_cut = median + kappa_high * stdev;
269 cpl_size rej_orig = cpl_image_count_rejected(ima_wrp);
271 if (lo_cut < hi_cut) {
272 cpl_mask_threshold_image(image_mask, ima_wrp, lo_cut, hi_cut, CPL_BINARY_0);
274 rej_new = cpl_image_count_rejected(ima_wrp);
276 if (rej_orig == rej_new){
284 if (rej_new == nx * ny) {
287 e = CPL_ERROR_ILLEGAL_INPUT;
289 *skymed = cpl_image_get_mean( ima_wrp);
290 *skysig = cpl_image_get_stdev(ima_wrp);
294 cpl_image_unwrap(ima_wrp);
316 ap_t *ap,
double x,
double y,
double *skylev,
double *skyrms)
319 cpl_size nbx = ap->backmap.nbx;
320 cpl_size nby = ap->backmap.nby;
321 cpl_size nbsize = ap->backmap.nbsize;
322 double **bvals = ap->backmap.bvals;
325 cpl_size i = (cpl_size)(x + (x < 0 ? -0.5 : 0.5));
326 cpl_size j = (cpl_size)(y + (y < 0 ? -0.5 : 0.5));
329 cpl_size nbsizo2 = nbsize / 2;
331 cpl_size ibx = (i + nbsizo2) / nbsize;
332 cpl_size ibxp1 = ibx + 1;
333 ibx = CPL_MIN(nbx, CPL_MAX(1, ibx));
334 ibxp1 = CPL_MIN(nbx, ibxp1);
336 cpl_size iby = (j + nbsizo2) / nbsize;
337 cpl_size ibyp1 = iby + 1;
338 iby = CPL_MIN(nby, CPL_MAX(1, iby));
339 ibyp1 = CPL_MIN(nby, ibyp1);
341 double fnbsize = 1. / (double)nbsize;
342 double delx = (i - nbsize * ibx + nbsizo2) * fnbsize;
343 double dely = (j - nbsize * iby + nbsizo2) * fnbsize;
348 double t1 = (1. - dely) * bvals[iby - 1][ibx - 1] + dely * bvals[ibyp1 - 1][ibx - 1];
349 double t2 = (1. - dely) * bvals[iby - 1][ibxp1 - 1] + dely * bvals[ibyp1 - 1][ibxp1 - 1];
351 *skylev = (1. - delx) * t1 + delx * t2;
353 *skyrms = 0.25 * ( fabs(bvals[iby - 1][ibx - 1] - *skylev)
354 + fabs(bvals[ibyp1 - 1][ibx - 1] - *skylev)
355 + fabs(bvals[iby - 1][ibxp1 - 1] - *skylev)
356 + fabs(bvals[ibyp1 - 1][ibxp1 - 1] - *skylev)
376static cpl_image * hdrl_sigclipfilter_image_grid(
377 const cpl_image *ima, cpl_matrix *x, cpl_matrix *y,
378 cpl_size filtersize_x, cpl_size filtersize_y)
380 cpl_error_ensure(ima != NULL, CPL_ERROR_NULL_INPUT,
381 return NULL,
"NULL input image");
383 cpl_error_ensure(filtersize_x > 0 && filtersize_y > 0 , CPL_ERROR_INCOMPATIBLE_INPUT,
384 return NULL,
"All function parameters must be greater then Zero");
386 const cpl_size nx = cpl_image_get_size_x(ima);
387 const cpl_size ny = cpl_image_get_size_y(ima);
389 const cpl_size steps_x = cpl_matrix_get_nrow(x);
390 const cpl_size steps_y = cpl_matrix_get_nrow(y);
392 cpl_image *ima_local = cpl_image_new(steps_x, steps_y, CPL_TYPE_DOUBLE);
393 cpl_image_get_bpm(ima_local);
395 HDRL_OMP(omp parallel
for)
396 for (cpl_size iy = 0; iy < steps_y; iy++) {
398 cpl_size middlep_y = cpl_matrix_get(y, iy, 0);
400 for (cpl_size ix = 0; ix < steps_x; ix++) {
402 cpl_size middlep_x = cpl_matrix_get(x, ix, 0);
404 cpl_size lowerlimit_x = CPL_MAX(middlep_x - filtersize_x, 1 );
405 cpl_size lowerlimit_y = CPL_MAX(middlep_y - filtersize_y, 1 );
406 cpl_size upperlimit_x = CPL_MIN(middlep_x + filtersize_x, nx);
407 cpl_size upperlimit_y = CPL_MIN(middlep_y + filtersize_y, ny);
409 cpl_image *ima_cut = cpl_image_extract(ima, lowerlimit_x, lowerlimit_y, upperlimit_x, upperlimit_y);
413 cpl_image_set(ima_local, ix + 1, iy + 1, median.data);
416 if ( isnan(median.data)
417 || cpl_image_count_rejected(ima_cut) >= 0.25 * 2 * (filtersize_x * filtersize_y))
419 cpl_image_reject(ima_local, ix + 1, iy + 1);
422 cpl_image_delete(ima_cut);
441static cpl_matrix * matrix_linspace(cpl_size start, cpl_size stop, cpl_size step)
443 cpl_matrix * x = cpl_matrix_new(stop / step, 1);
444 for (intptr_t i = 0; start + i * step < stop && i < stop / step; i++) {
445 cpl_matrix_set(x, i, 0, start + i * step);
void hdrl_backest(ap_t *ap, double x, double y, double *skylev, double *skyrms)
Work out estimated sky for a pixel position.
cpl_error_code hdrl_background(ap_t *ap, cpl_size nbsize, cpl_size bkg_subtr, hdrl_casu_result *res)
Model and create background map.
cpl_error_code hdrl_backstats(ap_t *ap, double *skymed, double *skysig)
Work out robust background estimate over a whole input image.
cpl_error_code hdrl_bfilt(double **xbuf, cpl_size nx, cpl_size ny)
Do bilinear median and linear filtering on background values.
hdrl_value hdrl_image_get_sigclip_mean(const hdrl_image *self, double kappa_low, double kappa_high, int niter)
computes the sigma-clipped mean and associated error of an image.
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
cpl_error_code sort_array(void *a, cpl_size nE, cpl_size sE, hdrl_sort_type type, cpl_sort_direction dir)
sort_array hdrl function for order arrays with know types. Using the type parameter for select the co...