29#include "hdrl_prototyping.h"
61static cpl_image *hdrl_mirror_edges(cpl_image *image,
int dx,
int dy);
62static cpl_image *hdrl_gen_lowpass(
int xs,
int ys,
double sigma_x,
85 cpl_image *clean_flat;
87 cpl_image *eflat_complex=NULL;
88 cpl_image *eflat_real=NULL;
90 cpl_image *filter_image=NULL;
91 cpl_image *filter_image_complex=NULL;
99 cpl_type ima_type = cpl_image_get_type(ima);
101 clean_flat = cpl_image_cast(ima, CPL_TYPE_FLOAT);
102 cpl_detector_interpolate_rejected(clean_flat);
106 eflat = hdrl_mirror_edges(clean_flat, mirrorx, mirrory);
108 if (clean_flat != NULL) {
109 cpl_image_delete(clean_flat);
114 cpl_msg_error(cpl_func,
"Filter image is NULL");
118 xsize = cpl_image_get_size_x(eflat);
119 ysize = cpl_image_get_size_y(eflat);
122 sigma_y = (double)(sigma_x * ysize) / xsize;
126 filter_image = hdrl_gen_lowpass(xsize, ysize, sigma_x, sigma_y);
127 if(filter_image == NULL){
128 cpl_msg_error(cpl_func,
"Filter image is NULL");
129 cpl_image_delete(eflat);
133 eflat_complex = cpl_image_new(xsize,ysize, CPL_TYPE_FLOAT_COMPLEX);
134 eflat_real = cpl_image_new(xsize,ysize, CPL_TYPE_FLOAT);
135 filter_image_complex =cpl_image_cast(filter_image,CPL_TYPE_FLOAT_COMPLEX);
138 cpl_image_delete(filter_image);
142 cpl_fft_image(eflat_complex, eflat, CPL_FFT_FORWARD);
144 cpl_image_delete(eflat);
147 cpl_image_multiply(eflat_complex,filter_image_complex);
151 cpl_fft_image(eflat_real, eflat_complex,CPL_FFT_BACKWARD);
153 cpl_image_delete(eflat_complex);
154 cpl_image_delete(filter_image_complex);
157 flat_real = cpl_image_extract(eflat_real, mirrorx+1, mirrory+1,
158 xsize-mirrorx, ysize-mirrory);
160 if (flat_real == NULL) {
161 cpl_msg_error (cpl_func,
"Real extracted image is NULL. <%s>", cpl_error_get_message());
164 cpl_image_delete(eflat_real);
166 cpl_image * out_double = cpl_image_cast(flat_real, ima_type);
167 cpl_image_delete(flat_real);
188static cpl_image * hdrl_gen_lowpass(
int xs,
int ys,
double sigma_x,
197 double gaussval= 0.0;
200 cpl_image *lowpass_image;
203 lowpass_image = cpl_image_new (xs, ys, CPL_TYPE_FLOAT);
204 if (lowpass_image == NULL) {
205 cpl_msg_error (cpl_func,
"Cannot generate lowpass filter <%s>",cpl_error_get_message());
212 data = cpl_image_get_data_float(lowpass_image);
224 data[0] = (float)1.0;
227 for (i=1 ; i<=hlx ; i++) {
228 x = (double)i / sigma_x;
229 gaussval = (double)exp(-0.5*x*x);
231 data[xs-i] = gaussval;
234 for (j=1; j<=hly ; j++) {
235 double y = (double)j / sigma_y;
237 data[j*xs] = (double)exp(-0.5*y*y);
238 data[(ys-j)*xs] = (
double)exp(-0.5*y*y);
240 for (i=1 ; i<=hlx ; i++) {
242 x = (double) i / sigma_x;
243 gaussval = (double)exp (-0.5*(x*x+y*y));
244 data[j*xs+i] = gaussval;
245 data[(j+1)*xs-i] = gaussval;
246 data[(ys-j)*xs+i] = gaussval;
247 data[(ys+1-j)*xs-i] = gaussval;
259 return lowpass_image;
272cpl_image *hdrl_mirror_edges(cpl_image *image,
int dx,
int dy)
275 intptr_t xs = cpl_image_get_size_x(image);
276 intptr_t ys = cpl_image_get_size_y(image);
277 intptr_t xx = xs+(2*dx);
278 intptr_t yy = ys+(2*dy);
279 float * data = cpl_image_get_data_float(image);
280 cpl_image * big_image = cpl_image_new(xx, yy, CPL_TYPE_FLOAT);
281 float * out_data = cpl_image_get_data_float(big_image);
283 for (intptr_t j=0; j<ys ; j++){
284 intptr_t inrow = j*xs;
285 intptr_t outrow = (j+dy)*xx;
287 for (intptr_t i=0; i<xs ; i++){
288 out_data[outrow+dx+i] = data[inrow+i];
291 for (intptr_t i=0; i<dx; i++){
292 out_data[outrow+i] = data[inrow+dx-i-1];
293 out_data[outrow+xs+dx+i] = data[inrow+xs-i-1];
298 for (intptr_t j=0; j<dy ; j++) {
300 for (intptr_t i=0; i<xx; i++) {
301 out_data[j*xx+i] = out_data[(2*dy-j-1)*xx+i];
302 out_data[(yy-j-1)*xx+i] = out_data[(yy-2*dy+j)*xx+i];
311cpl_image * hdrl_mime_image_polynomial_bkg(cpl_image * image,
312 int dim_X,
int dim_Y,
313 cpl_matrix ** coeffs){
314 cpl_imagelist * imlist;
315 cpl_imagelist * bkg_imlist;
316 cpl_image * bkg_image;
317 cpl_image * bkg_image_origtype;
321 cpl_error_set_message(cpl_func,
322 CPL_ERROR_NULL_INPUT,
323 "Null input image provided");
327 ima_type = cpl_image_get_type(image);
329 imlist = cpl_imagelist_new();
330 bkg_imlist = cpl_imagelist_new();
331 cpl_imagelist_set(imlist, image, 0);
335 cpl_imagelist_unwrap(imlist);
336 bkg_image = cpl_imagelist_unset(bkg_imlist, 0);
337 cpl_imagelist_delete(bkg_imlist);
339 bkg_image_origtype=cpl_image_cast(bkg_image, ima_type);
340 cpl_image_delete(bkg_image);
342 return bkg_image_origtype;
363 const cpl_imagelist * images,
364 cpl_imagelist * bkg_images,
374 cpl_matrix * poly_tensors;
377 cpl_matrix * weights;
379 cpl_msg_debug(cpl_func,
"Polynomial with X, Y dimensions %2d, %2d.",
383 cpl_error_ensure(images != NULL, CPL_ERROR_DATA_NOT_FOUND,
384 return CPL_ERROR_DATA_NOT_FOUND,
"list of dithered images is empty");
386 cpl_error_ensure(cpl_imagelist_is_uniform(images) == 0, CPL_ERROR_INCOMPATIBLE_INPUT,
387 return CPL_ERROR_INCOMPATIBLE_INPUT,
"input image list have non uniform data");
392 n_images = cpl_imagelist_get_size(images);
393 n_x = cpl_image_get_size_x(cpl_imagelist_get_const(images, 0));
394 n_y = cpl_image_get_size_y(cpl_imagelist_get_const(images, 0));
400 n_tensor = cpl_matrix_get_ncol(poly_tensors);
401 *coeffs = cpl_matrix_new(n_tensor, n_images);
410 for (im = 0; im < n_images; im++){
411 cpl_matrix * image_data;
412 cpl_matrix * bkg_image_data;
413 cpl_matrix * masked_tensors;
414 cpl_matrix * masked_image;
415 cpl_matrix * image_double_wrap;
418 cpl_image * bkg_image;
419 cpl_image * image_double;
420 cpl_image * bkg_image_float;
422 double alpha = 1.0e-10;
424 image_data = cpl_matrix_new(n_x*n_y, 1);
425 bkg_image_data = cpl_matrix_new(n_x*n_y, 1);
426 masked_image = cpl_matrix_new(n_x * n_y, 1);
427 masked_tensors = cpl_matrix_new(n_x * n_y, n_tensor);
434 image = cpl_image_duplicate(cpl_imagelist_get_const(images, im));
435 mask_bin = cpl_image_get_bpm(image);
436 if (mask_bin == NULL) {
437 cpl_msg_info(cpl_func,
"mask not available");
438 cpl_matrix_delete(poly_tensors);
439 cpl_matrix_delete(image_data);
440 cpl_matrix_delete(bkg_image_data);
441 cpl_matrix_delete(masked_image);
442 cpl_matrix_delete(masked_tensors);
443 cpl_image_delete(image);
444 return cpl_error_set(cpl_func, CPL_ERROR_DATA_NOT_FOUND);
447 image_double = cpl_image_cast(image, CPL_TYPE_DOUBLE);
448 image_double_wrap = cpl_matrix_wrap(n_x*n_y, 1,
449 cpl_image_get_data_double(image_double));
450 cpl_matrix_copy(image_data, image_double_wrap, 0, 0);
455 cpl_matrix_copy(masked_tensors, poly_tensors, 0, 0);
459 cpl_matrix_copy(masked_image, image_data, 0, 0);
468 cpl_matrix_copy(*coeffs, coeff, 0, im);
477 bkg_image = cpl_image_wrap_double(n_x, n_y,
478 cpl_matrix_get_data(bkg_image_data));
479 bkg_image_float = cpl_image_cast(bkg_image, CPL_TYPE_FLOAT);
480 cpl_imagelist_set(bkg_images, bkg_image_float, im);
482 cpl_matrix_delete(image_data);
483 cpl_matrix_delete(bkg_image_data);
484 cpl_matrix_delete(masked_image);
485 cpl_matrix_delete(masked_tensors);
486 cpl_matrix_delete(coeff);
487 cpl_image_delete(image);
488 cpl_image_delete(image_double);
489 cpl_matrix_unwrap(image_double_wrap);
490 cpl_image_unwrap(bkg_image);
496 cpl_matrix_delete(weights);
497 cpl_matrix_delete(poly_tensors);
498 return CPL_ERROR_NONE;
522 double ax, ay, bx, by;
525 if (nx < 2 || ny < 2 || npx < 1 || npy < 1)
527 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
552 cpl_matrix_delete(x);
553 cpl_matrix_delete(y);
554 cpl_matrix_delete(xpolys);
555 cpl_matrix_delete(ypolys);
582 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
587 nodes = cpl_matrix_new(n, 1);
588 data = cpl_matrix_get_data(nodes);
591 h = (b - a) / (n - 1);
592 for (i = 0; i < n; i++)
618 const cpl_matrix * x)
623 double midpoint, scale;
629 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
633 if (npoly < 1 || a == b)
635 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
640 nr = cpl_matrix_get_nrow(x) * cpl_matrix_get_ncol(x);
643 polys = cpl_matrix_new(nr, npoly);
646 midpoint = 0.5 * (a + b);
647 scale = 2.0 / (b - a);
650 m = cpl_matrix_get_data(polys);
651 for (i = 0; i < nr; i++, m += npoly)
655 m = cpl_matrix_get_data(polys);
656 mx = cpl_matrix_get_data_const(x);
658 for (i = 0; i < nr; i++, m += npoly)
659 m[1] = scale * (mx[i] - midpoint);
664 m = cpl_matrix_get_data(polys);
665 for (i = 0; i < nr; i++, m += npoly)
667 double xi = scale * (mx[i] - midpoint);
668 for (j = 2; j < npoly; j++)
670 double alpha = (2.0 * j - 1.0) / j;
671 double beta = (j - 1.0) / j;
672 m[j] = alpha * xi * m[j - 1] - beta * m[j - 2];
694 cpl_matrix * mat1,
const cpl_matrix * mat2)
701 int j1, j2, nc, col_count;
704 if (mat1 == NULL || mat2 == NULL)
706 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
711 nc1 = cpl_matrix_get_ncol(mat1);
712 nc2 = cpl_matrix_get_ncol(mat2);
716 for (j1 = 0; j1 < nc1; j1++)
718 for (j2 = 0; j2 < nc2; j2++)
719 nc += (j1 * (nc2 - 1) + j2 * (nc1 - 1) <=
720 (nc1 - 1) * (nc2 - 1) ? 1 : 0);
724 repl1 = cpl_matrix_new(cpl_matrix_get_nrow(mat1), nc);
725 repl2 = cpl_matrix_new(cpl_matrix_get_nrow(mat2), nc);
728 for (j1 = 0; j1 < nc1; j1++)
730 for (j2 = 0; j2 < nc2; j2++)
732 if (j1 * (nc2 - 1) + j2 * (nc1 - 1) <= (nc1 - 1) * (nc2 - 1))
743 cpl_matrix_delete(repl1);
744 cpl_matrix_delete(repl2);
763 cpl_matrix * mat2,
int j_2)
770 if (mat1 == NULL || mat2 == NULL)
771 return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
773 if (cpl_matrix_get_nrow(mat1) != cpl_matrix_get_nrow(mat2))
774 return cpl_error_set(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT);
776 if (j_1 < 0 || j_1 >= cpl_matrix_get_ncol(mat1) || j_2 < 0 ||
777 j_2 >= cpl_matrix_get_ncol(mat2))
778 return cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
781 nr = cpl_matrix_get_nrow(mat1);
782 nc1 = cpl_matrix_get_ncol(mat1);
783 nc2 = cpl_matrix_get_ncol(mat2);
784 m1 = cpl_matrix_get_data_const(mat1) + j_1;
785 m2 = cpl_matrix_get_data(mat2) + j_2;
788 for (i = 0; i < nr; i++, m1 += nc1, m2 += nc2)
791 return CPL_ERROR_NONE;
807 mat1,
const cpl_matrix * mat2)
817 if (mat1 == NULL || mat2 == NULL)
819 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
823 if (cpl_matrix_get_ncol(mat1) != cpl_matrix_get_ncol(mat2))
825 cpl_error_set(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT);
830 nr1 = cpl_matrix_get_nrow(mat1);
831 nr2 = cpl_matrix_get_nrow(mat2);
832 nc = cpl_matrix_get_ncol(mat1);
835 tensor = cpl_matrix_new(nr1 * nr2, nc);
838 m1 = cpl_matrix_get_data_const(mat1);
839 t = cpl_matrix_get_data(tensor);
840 for (i1 = 0; i1 < nr1; i1++, m1 += nc)
844 m2 = cpl_matrix_get_data_const(mat2);
845 for (i2 = 0; i2 < nr2; i2++, m2 += nc, t += nc)
848 for (j = 0; j < nc; j++)
849 t[j] = m1[j] * m2[j];
875 double ax, ay, bx, by, v;
879 if (nx < 2 || ny < 2)
881 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
899 m = cpl_matrix_get_data(x);
900 for (i = 0; i < nx; i++)
903 v = 1.0 / sqrt(1.0 - v * v);
907 m = cpl_matrix_get_data(y);
908 for (i = 0; i < ny; i++)
911 v = 1.0 / sqrt(1.0 - v * v);
920 cpl_matrix_fill(x, 1.0);
921 cpl_matrix_fill(y, 1.0);
927 cpl_matrix_delete(x);
928 cpl_matrix_delete(y);
948 const cpl_binary *mk;
952 if (mat == NULL || mask == NULL)
953 return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
955 if (cpl_matrix_get_nrow(mat) !=
956 cpl_mask_get_size_x(mask) * cpl_mask_get_size_y(mask))
957 return cpl_error_set(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT);
960 nr = cpl_matrix_get_nrow(mat);
961 nc = cpl_matrix_get_ncol(mat);
962 m = cpl_matrix_get_data(mat);
963 mk = cpl_mask_get_data_const(mask);
966 for (i = 0; i < nr; i++, mk++, m += nc)
968 if (*mk == CPL_BINARY_1)
970 for (j = 0; j < nc; j++)
975 return CPL_ERROR_NONE;
992 const cpl_matrix * d, cpl_matrix * dmat)
1000 if (mat == NULL || d == NULL || dmat == NULL)
1002 return cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
1005 if (cpl_matrix_get_nrow(mat) !=
1006 cpl_matrix_get_nrow(d) * cpl_matrix_get_ncol(d))
1008 return cpl_error_set(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT);
1011 if (cpl_matrix_get_ncol(mat) != cpl_matrix_get_ncol(dmat) ||
1012 cpl_matrix_get_nrow(mat) != cpl_matrix_get_nrow(dmat))
1014 return cpl_error_set(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT);
1018 nr = cpl_matrix_get_nrow(mat);
1019 nc = cpl_matrix_get_ncol(mat);
1021 m = cpl_matrix_get_data_const(mat);
1022 di = cpl_matrix_get_data_const(d);
1023 dm = cpl_matrix_get_data(dmat);
1026 for (i = 0; i < nr; i++, m += nc, dm += nc)
1028 for (j = 0; j < nc; j++)
1029 dm[j] = di[i] * m[j];
1032 return CPL_ERROR_NONE;
1052 const cpl_matrix * rhs,
double alpha)
1055 cpl_matrix *solution;
1056 cpl_error_code error;
1059 if (mat == NULL || rhs == NULL)
1061 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
1065 if (cpl_matrix_get_nrow(mat) != cpl_matrix_get_nrow(rhs))
1067 cpl_error_set(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT);
1073 error = cpl_matrix_decomp_chol(normal);
1075 if (error != CPL_ERROR_NONE)
1077 cpl_matrix_delete(normal);
1083 error = cpl_matrix_solve_chol(normal, solution);
1084 cpl_matrix_delete(normal);
1086 if (error != CPL_ERROR_NONE)
1088 cpl_matrix_delete(solution);
1120 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
1126 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1131 nr = cpl_matrix_get_nrow(mat);
1132 nc = cpl_matrix_get_ncol(mat);
1135 normal = cpl_matrix_new(nc, nc);
1138 p = cpl_matrix_get_data(normal);
1139 for (i = 0; i < nc; i++, p += nc)
1141 for (j = i; j < nc; j++)
1143 m = cpl_matrix_get_data_const(mat);
1145 for (k = 0; k < nr; k++, m += nc)
1152 p = cpl_matrix_get_data(normal);
1153 for (i = 0; i < nc; i++)
1154 p[nc * i + i] += alpha;
1174 mat1,
const cpl_matrix * mat2)
1176 cpl_matrix *product;
1187 if (mat1 == NULL || mat2 == NULL)
1189 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
1193 if (cpl_matrix_get_nrow(mat1) != cpl_matrix_get_nrow(mat2))
1195 cpl_error_set(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT);
1200 nr = cpl_matrix_get_ncol(mat1);
1201 nc = cpl_matrix_get_ncol(mat2);
1202 common = cpl_matrix_get_nrow(mat1);
1206 product = cpl_matrix_new(nr, nc);
1207 p = cpl_matrix_get_data(product);
1210 for (i = 0; i < nr; i++, p += nc)
1212 for (j = 0; j < nc; j++)
1214 m1 = cpl_matrix_get_data_const(mat1);
1215 m2 = cpl_matrix_get_data_const(mat2);
1217 for (k = 0; k < common; k++, m1 += nr, m2 += nc)
1218 sum += m1[i] * m2[j];
1242 const cpl_matrix * mat2, cpl_matrix * product)
1253 if (mat1 == NULL || mat2 == NULL || product == NULL)
1255 cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
1256 return CPL_ERROR_NONE;
1259 if (cpl_matrix_get_ncol(mat1) != cpl_matrix_get_nrow(mat2) ||
1260 cpl_matrix_get_nrow(mat1) != cpl_matrix_get_nrow(product) ||
1261 cpl_matrix_get_ncol(mat2) != cpl_matrix_get_ncol(product))
1263 cpl_error_set(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT);
1264 return CPL_ERROR_NONE;
1268 nr = cpl_matrix_get_nrow(mat1);
1269 nc = cpl_matrix_get_ncol(mat2);
1270 common = cpl_matrix_get_ncol(mat1);
1273 m1 = cpl_matrix_get_data_const(mat1);
1274 p = cpl_matrix_get_data(product);
1275 for (i = 0; i < nr; i++, m1 += cpl_matrix_get_ncol(mat1), p += nc)
1277 for (j = 0; j < nc; j++)
1279 m2 = cpl_matrix_get_data_const(mat2);
1281 for (k = 0; k < common; k++, m2 += cpl_matrix_get_ncol(mat2))
1282 sum += m1[k] * m2[j];
1287 return CPL_ERROR_NONE;
cpl_error_code hdrl_mime_compute_polynomial_bkg(const cpl_imagelist *images, cpl_imagelist *bkg_images, int dim_X, int dim_Y, cpl_matrix **coeffs)
Fit smooth background for a list of images.
cpl_matrix * hdrl_mime_legendre_tensors_create(int nx, int ny, int npx, int npy)
Create tensor products of Legendre polynomials.
cpl_error_code hdrl_mime_matrix_mask_rows(cpl_matrix *mat, const cpl_mask *mask)
Fill matrix rows with zeros as indicated by a mask.
cpl_matrix * hdrl_mime_linalg_solve_tikhonov(const cpl_matrix *mat, const cpl_matrix *rhs, double alpha)
Solve an overdetermined linear system in the least-squares sense.
cpl_error_code hdrl_mime_matrix_copy_column(const cpl_matrix *mat1, int j_1, cpl_matrix *mat2, int j_2)
Copy a column from one matrix to another matrix.
cpl_matrix * hdrl_mime_linalg_pairwise_column_tensor_products_create(const cpl_matrix *mat1, const cpl_matrix *mat2)
Create selected pairwise tensor products of the columns of two matrices.
cpl_matrix * hdrl_mime_matrix_product_left_transpose_create(const cpl_matrix *mat1, const cpl_matrix *mat2)
Create the product of the transpose of a matrix with another matrix.
cpl_error_code hdrl_mime_matrix_rescale_rows(const cpl_matrix *mat, const cpl_matrix *d, cpl_matrix *dmat)
Multiply the rows of a matrix by given factors.
cpl_matrix * hdrl_mime_tensor_weights_create(int nx, int ny)
Create tensor product weights.
cpl_matrix * hdrl_mime_legendre_polynomials_create(int npoly, double a, double b, const cpl_matrix *x)
Create the Legendre polynomial basis on the interval (a,b).
cpl_image * hdrl_get_spatial_freq(cpl_image *ima, double gausfilt, int mirrorx, int mirrory)
Get low spatial frequency componenets from an image using the FFTW.
cpl_matrix * hdrl_mime_matrix_linspace_create(int n, double a, double b)
Create equally spaced nodes.
cpl_matrix * hdrl_mime_linalg_normal_equations_create(const cpl_matrix *mat, double alpha)
Create the matrix transpose(A) * A + alpha for given A and alpha.
cpl_matrix * hdrl_mime_linalg_tensor_products_columns_create(const cpl_matrix *mat1, const cpl_matrix *mat2)
Create the tensor products of the columns of two matrices.
cpl_error_code hdrl_mime_matrix_product(const cpl_matrix *mat1, const cpl_matrix *mat2, cpl_matrix *product)
Fill a matrix with the product of two given matrices.