32 #include <fors_image.h>
35 #include <fors_utils.h>
36 #include <fors_pfits.h>
37 #include <fors_double.h>
38 #include <fors_saturation.h>
39 #include <fors_subtract_bias.h>
52 const cpl_type FORS_IMAGE_TYPE = CPL_TYPE_FLOAT;
53 #define FORS_IMAGE_TYPE_MAX FLT_MAX
66 max_filter(
const float *ibuffer,
float *obuffer,
int length,
int size)
70 int end = length - size / 2;
74 for (i = start; i < end; i++) {
75 max = ibuffer[i-start];
76 for (j = i - start + 1; j <= i + start; j++)
82 for (i = 0; i < start; i++)
83 obuffer[i] = obuffer[start];
85 for (i = end; i < length; i++)
86 obuffer[i] = obuffer[end-1];
106 assure( data != NULL,
return NULL, NULL );
107 assure( variance != NULL,
return NULL, NULL );
120 assure( cpl_image_get_size_x(data) == cpl_image_get_size_x(variance) &&
121 cpl_image_get_size_y(data) == cpl_image_get_size_y(variance),
123 "Incompatible data and weight image sizes: "
124 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
125 " and %"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT,
126 cpl_image_get_size_x(data), cpl_image_get_size_y(data),
127 cpl_image_get_size_x(variance), cpl_image_get_size_y(variance));
129 assure( cpl_image_get_min(variance) >= 0,
return NULL,
130 "Variances must be non-negative, minimum is %g. \n"
131 "This is most likely a software bug. "
132 "You may contact usd-help@eso.org which can provide a workaround.",
133 cpl_image_get_min(variance));
135 image = cpl_malloc(
sizeof(*image));
138 image->variance = variance;
153 assure( image != NULL,
return NULL, NULL );
156 cpl_image_duplicate(image->variance));
166 if (image && *image) {
167 cpl_image_delete((*image)->data);
168 cpl_image_delete((*image)->variance);
169 cpl_free(*image); *image = NULL;
193 fors_image_dump(
const fors_image *image, FILE *file)
196 fprintf(file,
"Null image\n");
201 fprintf(file,
"Data:\n");
202 stats = cpl_stats_new_from_image(image->data, CPL_STATS_ALL);
203 cpl_stats_dump(stats, CPL_STATS_ALL, file);
204 cpl_stats_delete(stats);
206 fprintf(file,
"Variance:\n");
207 stats = cpl_stats_new_from_image(image->variance, CPL_STATS_ALL);
208 cpl_stats_dump(stats, CPL_STATS_ALL, file);
209 cpl_stats_delete(stats);
219 double_list_delete(&sat_percent, double_delete); \
238 fors_image_list *ilist = fors_image_list_new();
239 double_list *sat_percent = double_list_new();
241 assure( frames != NULL,
return ilist, NULL );
242 assure( !cpl_frameset_is_empty(frames),
return ilist,
"Empty frameset");
247 for (
int i =0; i< cpl_frameset_get_size(frames); i ++)
249 f = cpl_frameset_get_position_const(frames, i);
253 fors_image_list_insert(ilist, ima);
272 const fors_image_list *
275 return (
const fors_image_list *)
282 cpl_image_delete(temp); \
295 cpl_image *data = NULL;
296 cpl_image *variance = NULL;
297 cpl_image *temp = NULL;
298 const char *filename;
302 assure( frame != NULL,
return image, NULL );
304 filename = cpl_frame_get_filename(frame);
305 assure( filename != NULL,
return image,
306 "NULL filename received");
308 cpl_msg_info(cpl_func,
"Loading %s: %s",
310 (cpl_frame_get_tag(frame) != NULL) ?
311 cpl_frame_get_tag(frame) :
"NULL",
315 data = cpl_image_load(filename,
316 FORS_IMAGE_TYPE, plane, extension);
318 assure( !cpl_error_get_code(),
return image,
319 "Could not load image from %s extension %d",
320 filename, extension);
324 if (cpl_frame_get_nextensions(frame) == 0) {
327 variance = cpl_image_new(
328 cpl_image_get_size_x(data),
329 cpl_image_get_size_y(data),
338 variance = cpl_image_load(filename,
339 FORS_IMAGE_TYPE, plane, extension);
341 assure( !cpl_error_get_code(),
return image,
342 "Could not load image from %s extension %d",
343 filename, extension);
345 cpl_image_power(variance, 2);
347 assure( cpl_image_get_min(variance) >= 0,
return image,
348 "Illegal minimum variance: %g",
349 cpl_image_get_min(variance));
351 cpl_image_delete(temp); temp = NULL;
364 cpl_image_delete(sigma); \
365 cpl_propertylist_delete(extension_header); \
378 const cpl_propertylist *err_header,
379 const char *filename)
381 cpl_propertylist *extension_header = NULL;
382 cpl_image *sigma = NULL;
384 assure( image != NULL,
return, NULL );
386 assure( filename != NULL,
return, NULL );
388 cpl_image_save(image->data, filename, CPL_BPP_IEEE_FLOAT, header,
390 assure( !cpl_error_get_code(),
return,
391 "Cannot save product %s", filename);
393 sigma = cpl_image_power_create(image->variance, 0.5);
395 if(err_header != NULL)
396 extension_header = cpl_propertylist_duplicate(err_header);
398 extension_header = cpl_propertylist_new();
399 cpl_propertylist_append_string(extension_header,
400 "EXTNAME",
"IMAGE.ERR");
402 cpl_image_save(sigma, filename, CPL_BPP_IEEE_FLOAT, extension_header,
404 assure( !cpl_error_get_code(),
return,
405 "Cannot save product %s", filename);
415 cpl_image_delete(var_bkg); \
416 cpl_image_delete(sigma_bkg); \
431 const char *filename_dat,
432 const char *filename_var,
435 cpl_propertylist *extension_header = NULL;
436 cpl_image *sigma_bkg = NULL;
437 cpl_image *var_bkg = NULL;
439 assure( image != NULL,
return, NULL );
441 assure( filename_dat != NULL,
return, NULL );
442 assure( filename_var != NULL,
return, NULL );
444 cpl_image_save(image->data, filename_dat, CPL_BPP_IEEE_FLOAT, header,
446 assure( !cpl_error_get_code(),
return,
447 "Cannot save product %s", filename_dat);
457 cpl_msg_info(cpl_func,
"Creating background error map");
459 bool filter_data =
false;
460 int xstep = radius/2;
467 int ystep = radius/2;
481 assure( !cpl_error_get_code(),
return,
482 "Median filtering failed");
484 sigma_bkg = cpl_image_power_create(var_bkg, 0.5);
486 cpl_image_save(sigma_bkg, filename_var,
487 CPL_BPP_IEEE_FLOAT, extension_header,
489 assure( !cpl_error_get_code(),
return,
490 "Cannot save product %s", filename_var);
505 assure( image != NULL,
return -1, NULL );
506 return cpl_image_get_size_x(image->data);
518 assure( image != NULL,
return -1, NULL );
519 return cpl_image_get_size_y(image->data);
530 assure( image != NULL,
return NULL, NULL );
532 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return NULL, NULL );
536 return cpl_image_get_data_float(image->data);
551 assure( image != NULL,
return, NULL );
553 cpl_image_abs(image->data);
570 assure( image != NULL,
return, NULL );
572 cpl_image_multiply(image->data, image->data);
577 cpl_image_multiply_scalar(image->variance, 2);
586 cpl_image_delete(temp); \
599 cpl_image *temp = NULL;
600 assure( left != NULL,
return, NULL );
601 assure( right != NULL,
return, NULL );
603 cpl_image_subtract(left->data, right->data);
606 cpl_image_add(left->variance, right->variance);
627 assure( left != NULL,
return, NULL );
628 assure( right != NULL,
return, NULL );
629 assure( cpl_image_get_size_x(left->data) == cpl_image_get_size_x(right) &&
630 cpl_image_get_size_y(left->data) == cpl_image_get_size_y(right),
632 "Incompatible data and weight image sizes: "
633 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
634 " and %"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT,
635 cpl_image_get_size_x(left->data),
636 cpl_image_get_size_y(left->data),
637 cpl_image_get_size_x(right),
638 cpl_image_get_size_y(right));
640 cpl_image_multiply(left->data, right);
641 cpl_image_multiply(left->variance, right);
642 cpl_image_multiply(left->variance, right);
668 assure( left != NULL,
return, NULL );
669 assure( right != NULL,
return, NULL );
670 assure( cpl_image_get_size_x(left->data) == cpl_image_get_size_x(right) &&
671 cpl_image_get_size_y(left->data) == cpl_image_get_size_y(right),
673 "Incompatible data and weight image sizes: "
674 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
675 " and %"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT,
676 cpl_image_get_size_x(left->data),
677 cpl_image_get_size_y(left->data),
678 cpl_image_get_size_x(right),
679 cpl_image_get_size_y(right));
682 int nx = cpl_image_get_size_x(right);
683 int ny = cpl_image_get_size_y(right);
684 float *datal = cpl_image_get_data_float(left->data);
685 float *datav = cpl_image_get_data_float(left->variance);
686 float *datar = cpl_image_get_data_float(right);
687 for (y = 0; y < ny; y++) {
688 for (x = 0; x < nx; x++) {
689 if (datar[x + nx*y] == 0) {
693 datav[x + nx*y] = FORS_IMAGE_TYPE_MAX;
698 cpl_image_divide(left->data, right);
699 cpl_image_divide(left->variance, right);
700 cpl_image_divide(left->variance, right);
708 fors_image_delete(&dupl); \
735 assure( left != NULL,
return, NULL );
736 assure( right != NULL,
return, NULL );
740 cpl_image_divide(left->data, dupl->data);
743 cpl_image_multiply(dupl->variance, left->data);
744 cpl_image_multiply(dupl->variance, left->data);
748 cpl_image_add(left->variance, dupl->variance);
752 cpl_image_divide(left->variance, dupl->data);
753 cpl_image_divide(left->variance, dupl->data);
758 int nx = cpl_image_get_size_x(left->data);
759 int ny = cpl_image_get_size_y(left->data);
760 float *datal = cpl_image_get_data_float(left->data);
761 float *datav = cpl_image_get_data_float(left->variance);
762 float *datar = cpl_image_get_data_float(right->data);
763 for (y = 0; y < ny; y++) {
764 for (x = 0; x < nx; x++) {
765 if (datar[x + nx*y] == 0) {
767 datav[x + nx*y] = FORS_IMAGE_TYPE_MAX;
779 cpl_image_delete(s22d12); \
795 cpl_image *s22d12 = NULL;
797 assure( left != NULL,
return, NULL );
798 assure( right != NULL,
return, NULL );
800 s22d12 = cpl_image_duplicate(right->variance);
801 cpl_image_multiply(s22d12, left->data);
802 cpl_image_multiply(s22d12, left->data);
804 cpl_image_multiply(left->variance, right->data);
805 cpl_image_multiply(left->variance, right->data);
806 cpl_image_add(left->variance, s22d12);
808 cpl_image_multiply(left->data, right->data);
831 assure( image != NULL,
return, NULL );
832 assure( ds <= 0,
return,
"Unsupported");
834 cpl_image_subtract_scalar(image->data, s);
856 assure( image != NULL,
return, NULL );
857 assure( s != 0,
return,
"Division by zero");
858 assure( ds <= 0,
return,
"Unsupported");
860 cpl_image_divide_scalar(image->data, s);
861 cpl_image_divide_scalar(image->variance, s*s);
882 assure( image != NULL,
return, NULL );
883 assure( ds <= 0,
return,
"Unsupported");
885 cpl_image_multiply_scalar(image->data, s);
886 cpl_image_multiply_scalar(image->variance, s*s);
894 cpl_image_delete(temp); \
911 cpl_image *temp = NULL;
913 assure( image != NULL,
return, NULL );
914 assure( b >= 0,
return,
"Negative base: %f", b);
915 assure( db <= 0,
return,
"Unsupported");
917 cpl_image_exponential(image->data, b);
921 cpl_image_multiply_scalar(image->variance, lnb*lnb);
922 cpl_image_multiply(image->variance, image->data);
923 cpl_image_multiply(image->variance, image->data);
939 assure( image != NULL,
return 0, NULL );
941 return cpl_image_get_min(image->data);
954 assure( image != NULL,
return 0, NULL );
956 return cpl_image_get_max(image->data);
970 assure( image != NULL,
return 0, NULL );
971 assure( dmean == NULL,
return 0,
"Unsupported");
973 return cpl_image_get_mean(image->data);
987 assure( image != NULL,
return 0, NULL );
988 assure( dmedian == NULL,
return 0,
"Unsupported");
990 return cpl_image_get_median(image->data);
1016 assure( image != NULL,
return, NULL );
1019 return,
"Cannot extraction region (%d, %d) - (%d, %d) of "
1020 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
" image",
1025 cpl_image *new_data = cpl_image_extract(image->data,
1028 cpl_image_delete(image->data);
1030 cpl_image* new_variance = cpl_image_extract(image->variance,
1033 cpl_image_delete(image->variance);
1035 image->data = new_data;
1036 image->variance = new_variance;
1078 const cpl_image *input = NULL;
1079 cpl_image *smooth = NULL;
1082 assure( image != NULL,
return smooth, NULL );
1083 passure( image->data != NULL,
return smooth );
1084 passure( image->variance != NULL,
return smooth );
1086 input = (use_data) ? image->data : image->variance;
1088 nx = cpl_image_get_size_x(input);
1089 ny = cpl_image_get_size_y(input);
1091 if (xstep < 1) xstep = 1;
1092 if (ystep < 1) ystep = 1;
1094 assure( 1 <= xstart && xstart <= xend && xend <= nx &&
1095 1 <= ystart && ystart <= yend && yend <= ny,
return smooth,
1096 "Illegal region (%d, %d) - (%d, %d) of %dx%d image",
1101 smooth = cpl_image_duplicate(input);
1104 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return smooth, NULL );
1106 const float *input_data = cpl_image_get_data_float_const(input);
1107 float *smooth_data = cpl_image_get_data_float(smooth);
1108 float *data = cpl_malloc((2*yradius + 1)*(2*xradius + 1)*
sizeof(*data));
1111 for (y = ystart; y < yend; y++) {
1118 int ylo = y - (yradius/ystep) * ystep;
1119 int yhi = y + (yradius/ystep) * ystep;
1121 while (ylo < ystart) ylo += ystep;
1122 while (yhi > yend ) yhi -= ystep;
1125 for (x = xstart; x < xend; x++) {
1126 int xlo = x - (xradius/xstep) * xstep;
1127 int xhi = x + (xradius/xstep) * xstep;
1129 while (xlo < xstart) xlo += xstep;
1130 while (xhi > xend ) xhi -= xstep;
1135 for (j = ylo; j <= yhi; j += ystep) {
1136 for (i = xlo; i <= xhi; i += xstep) {
1137 data[k++] = input_data[ (i-1) + (j-1)*nx ];
1142 smooth_data[ (x-1) + (y-1)*nx ] =
1154 cpl_image_delete(input); \
1157 fors_image_flat_fit_create(
fors_image *image,
1162 cpl_image *temp = NULL;
1163 cpl_image *input = NULL;
1164 cpl_image *smooth = NULL;
1167 assure( image != NULL,
return smooth, NULL );
1168 passure( image->data != NULL,
return smooth );
1169 assure( step > 0,
return smooth, NULL );
1170 assure( degree >= 0,
return smooth, NULL );
1175 nx = cpl_image_get_size_x(temp);
1176 ny = cpl_image_get_size_y(temp);
1182 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return smooth, NULL );
1190 const float *input_data = cpl_image_get_data_float_const(input);
1198 for (y = 0; y < ny; y += step) {
1200 for (x = 0; x < nx; x += step, pos += step) {
1201 if (input_data[pos] > level) {
1207 if (count < (degree+1)*(degree+2)) {
1208 step = sqrt((nx*nx)/((degree+1)*(degree+2))) / 2;
1211 cpl_msg_error(cpl_func,
"Flat field image too small (%dx%d). "
1212 "Please provide a smaller resampling step (a good "
1213 "value would be %d)", nx, ny, step);
1214 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1224 cpl_bivector *positions = cpl_bivector_new(count);
1225 double *xpos = cpl_bivector_get_x_data(positions);
1226 double *ypos = cpl_bivector_get_y_data(positions);
1227 cpl_vector *fluxes = cpl_vector_new(count);
1228 double *flux = cpl_vector_get_data(fluxes);
1231 for (y = 0; y < ny; y += step) {
1233 for (x = 0; x < nx; x += step, pos += step) {
1234 if (input_data[pos] > level) {
1237 flux[count] = input_data[pos];
1243 cpl_image_delete(input); input = NULL;
1250 cpl_polynomial *model = cpl_polynomial_fit_2d_create(positions,
1255 cpl_bivector_delete(positions);
1256 cpl_vector_delete(fluxes);
1258 smooth = cpl_image_new(nx, ny, FORS_IMAGE_TYPE);
1259 float *smooth_data = cpl_image_get_data_float(smooth);
1261 cpl_vector *point = cpl_vector_new(2);
1262 double *dpoint = cpl_vector_get_data(point);
1264 for (y = 0; y < ny; y++) {
1267 for (x = 0; x < nx; x++, pos++) {
1269 smooth_data[pos] = cpl_polynomial_eval(model, point);
1273 cpl_polynomial_delete(model);
1274 cpl_vector_delete(point);
1305 const cpl_image *input = NULL;
1306 cpl_image *hmaxima = NULL;
1307 cpl_image *maxima = NULL;
1310 assure( image != NULL,
return maxima, NULL );
1311 passure( image->data != NULL,
return maxima );
1312 passure( image->variance != NULL,
return maxima );
1314 input = (use_data) ? image->data : image->variance;
1316 nx = cpl_image_get_size_x(input);
1317 ny = cpl_image_get_size_y(input);
1323 hmaxima = cpl_image_duplicate(input);
1326 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return maxima, NULL );
1328 float *input_data = (
float *)cpl_image_get_data_float_const(input);
1329 float *maxima_data = cpl_image_get_data_float(hmaxima);
1332 for (y = 0; y < ny; y++) {
1333 const float *irow = input_data + y * nx;
1334 float *orow = maxima_data + y * nx;
1335 max_filter(irow, orow, nx, 2*xradius+1);
1338 cpl_image_turn(hmaxima, 1);
1344 maxima = cpl_image_duplicate(hmaxima);
1345 input_data = cpl_image_get_data_float(hmaxima);
1346 maxima_data = cpl_image_get_data_float(maxima);
1353 for (x = 0; x < nx; x++) {
1354 const float *irow = input_data + x * ny;
1355 float *orow = maxima_data + x * ny;
1356 max_filter(irow, orow, ny, 2*yradius+1);
1359 cpl_image_delete(hmaxima);
1361 cpl_image_turn(maxima, -1);
1377 assure( image != NULL,
return 0, NULL );
1378 assure( dstdev == NULL,
return 0,
"Unsupported");
1380 return cpl_image_get_stdev(image->data);
1385 cpl_mask_delete(rejected); \
1386 cpl_image_delete(im); \
1400 cpl_mask *rejected = NULL;
1401 cpl_image *im = NULL;
1403 assure( image != NULL,
return 0, NULL );
1404 assure( cut > 0,
return 0,
"Illegal cut: %f", cut );
1405 assure( dstdev == NULL,
return 0,
"Unsupported");
1409 im = cpl_image_duplicate(image->data);
1410 cpl_image_subtract_scalar(im, median);
1411 cpl_image_power(im, 2);
1414 rejected = cpl_mask_threshold_image_create(image->data,
1417 cpl_mask_not(rejected);
1418 cpl_image_reject_from_mask(im, rejected);
1420 double robust_stdev = sqrt(cpl_image_get_mean(im));
1423 return robust_stdev;
1443 assure( image != NULL,
return 0, NULL );
1444 assure( dmean == NULL,
return 0,
"Unsupported");
1446 avg = cpl_image_get_mean(image->variance);
1449 assure( avg >= 0,
return -1,
"Average variance is %f", avg);
1458 cpl_imagelist_delete(datlist); \
1459 cpl_imagelist_delete(varlist); \
1473 cpl_imagelist *datlist = NULL;
1474 cpl_imagelist *varlist = NULL;
1475 cpl_image *data = NULL;
1476 cpl_image *variance = NULL;
1480 assure( images != NULL,
return NULL, NULL );
1481 assure( fors_image_list_size(images) > 0,
return NULL,
1482 "Cannot stack zero images");
1484 i = fors_image_list_first_const(images);
1486 datlist = cpl_imagelist_new();
1487 varlist = cpl_imagelist_new();
1492 cpl_imagelist_set(datlist,
1493 cpl_image_duplicate(i->data),
1494 cpl_imagelist_get_size(datlist));
1495 cpl_imagelist_set(varlist,
1496 cpl_image_duplicate(i->variance),
1497 cpl_imagelist_get_size(varlist));
1498 i = fors_image_list_next_const(images);
1502 #ifdef CPL_IS_NOT_CRAP
1503 data = cpl_imagelist_collapse_create(datlist);
1505 variance = cpl_imagelist_collapse_create(varlist);
1512 cpl_image_divide_scalar(variance, N);
1522 cpl_imagelist_delete(datlist); \
1523 cpl_imagelist_delete(varlist); \
1540 cpl_imagelist *datlist = NULL;
1541 cpl_imagelist *varlist = NULL;
1542 cpl_image *data = NULL;
1543 cpl_image *variance = NULL;
1547 assure( images != NULL,
return NULL, NULL );
1548 assure( fors_image_list_size(images) > low + high,
return NULL,
1549 "Cannot reject more images than there are");
1550 assure( low*high >= 0 && low+high > 0,
return NULL,
1551 "Invalid minmax rejection criteria");
1553 i = fors_image_list_first_const(images);
1555 datlist = cpl_imagelist_new();
1556 varlist = cpl_imagelist_new();
1561 cpl_imagelist_set(datlist,
1562 cpl_image_duplicate(i->data),
1563 cpl_imagelist_get_size(datlist));
1564 cpl_imagelist_set(varlist,
1565 cpl_image_duplicate(i->variance),
1566 cpl_imagelist_get_size(varlist));
1567 i = fors_image_list_next_const(images);
1571 data = cpl_imagelist_collapse_minmax_create(datlist, low, high);
1572 variance = cpl_imagelist_collapse_minmax_create(varlist, low, high);
1574 cpl_image_divide_scalar(variance, N);
1594 int low,
int high,
int iter)
1596 cpl_imagelist *datlist = NULL;
1597 cpl_imagelist *varlist = NULL;
1598 cpl_image *data = NULL;
1599 cpl_image *variance = NULL;
1600 cpl_image *ngood = NULL;
1603 assure( images != NULL,
return NULL, NULL );
1605 i = fors_image_list_first_const(images);
1607 datlist = cpl_imagelist_new();
1608 varlist = cpl_imagelist_new();
1613 cpl_imagelist_set(datlist,
1614 cpl_image_duplicate(i->data),
1615 cpl_imagelist_get_size(datlist));
1616 cpl_imagelist_set(varlist,
1617 cpl_image_duplicate(i->variance),
1618 cpl_imagelist_get_size(varlist));
1619 i = fors_image_list_next_const(images);
1623 variance = cpl_imagelist_collapse_create(varlist);
1625 cpl_image_divide(variance, ngood);
1627 cpl_image_delete(ngood);
1647 cpl_imagelist *datlist = NULL;
1648 cpl_imagelist *varlist = NULL;
1649 cpl_image *data = NULL;
1650 cpl_image *variance = NULL;
1654 assure( images != NULL,
return NULL, NULL );
1655 assure( fors_image_list_size(images) > 0,
return NULL,
1656 "Cannot stack zero images");
1658 i = fors_image_list_first_const(images);
1660 datlist = cpl_imagelist_new();
1661 varlist = cpl_imagelist_new();
1664 cpl_imagelist_set(datlist,
1665 cpl_image_duplicate(i->data),
1666 cpl_imagelist_get_size(datlist));
1667 cpl_imagelist_set(varlist,
1668 cpl_image_duplicate(i->variance),
1669 cpl_imagelist_get_size(varlist));
1671 i = fors_image_list_next_const(images);
1675 #ifdef CPL_IS_NOT_CRAP
1676 data = cpl_imagelist_collapse_median_create(datlist);
1678 variance = cpl_imagelist_collapse_create(varlist);
1685 cpl_image_divide_scalar(variance, N);
1687 cpl_image_multiply_scalar(variance,
1716 int radius,
double color)
1718 assure( image != NULL,
return, NULL );
1720 assure( type == 0 || type == 1 || type == 2,
1721 return ,
"Unsupported type %d", type);
1723 assure( radius > 0,
return, NULL );
1727 for (i = 0; i < 360; i++) {
1730 int px = x + radius*cos(i/(2*M_PI));
1731 int py = y + radius*sin(i/(2*M_PI));
1733 if (1 <= px && px <= cpl_image_get_size_x(image->data) &&
1734 1 <= py && py <= cpl_image_get_size_y(image->data)) {
1735 cpl_image_set(image->data, px, py, color);
1736 cpl_image_set(image->variance, px, py, color > 0 ? color : 0);
1743 for (i = -radius; i <= radius; i++) {
1756 if (1 <= px && px <= cpl_image_get_size_x(image->data) &&
1757 1 <= py && py <= cpl_image_get_size_y(image->data)) {
1758 cpl_image_set(image->data , px, py, color);
1759 cpl_image_set(image->variance, px, py, color > 0 ? color : 0);
1767 hdrl_imagelist * fors_image_list_to_hdrl(
const fors_image_list * imalist)
1770 hdrl_imagelist * images_hdrl = hdrl_imagelist_new();
1771 const fors_image * target = fors_image_list_first_const(imalist);
1772 for(i = 0 ; i < fors_image_list_size(imalist); ++i)
1774 const cpl_image * ima_data = target->data;
1775 cpl_image * ima_error = cpl_image_power_create(target->variance, 0.5);
1776 cpl_mask * old_bpm = cpl_image_set_bpm(ima_error,
1777 cpl_mask_duplicate(cpl_image_get_bpm_const(ima_data)));
1778 cpl_mask_delete(old_bpm);
1779 hdrl_image * ima_hdrl = hdrl_image_create(ima_data, ima_error);
1780 hdrl_imagelist_set(images_hdrl, ima_hdrl,
1781 hdrl_imagelist_get_size(images_hdrl));
1782 target = fors_image_list_next_const(imalist);
1788 fors_image * fors_image_from_hdrl(
const hdrl_image * image)
1790 const cpl_image * data = hdrl_image_get_image_const(image);
1791 cpl_image * variance = cpl_image_power_create
1792 (hdrl_image_get_error_const(image), 2);
1800 #define LIST_ELEM fors_image
cpl_image * fors_image_filter_median_create(const fors_image *image, int xradius, int yradius, int xstart, int ystart, int xend, int yend, int xstep, int ystep, bool use_data)
Smooth image.
void fors_image_multiply_scalar(fors_image *image, double s, double ds)
Multiply by scalar.
void fors_image_abs(fors_image *image)
Absolute value.
double fors_image_get_stdev_robust(const fors_image *image, double cut, double *dstdev)
Get robust empirical stdev of data.
void fors_image_square(fors_image *image)
Squared.
const fors_image_list * fors_image_load_list_const(const cpl_frameset *frames)
Load imagelist.
fors_image * fors_image_new(cpl_image *data, cpl_image *variance)
Create image.
double fors_image_get_max(const fors_image *image)
Get max data value.
const float * fors_image_get_data_const(const fors_image *image)
Get pointer to data buffer.
void fors_image_subtract(fors_image *left, const fors_image *right)
Subtract images.
void fors_image_save_sex(const fors_image *image, const cpl_propertylist *header, const char *filename_dat, const char *filename_var, int radius)
Save image in format useable by SExtractor.
fors_image * fors_image_collapse_create(const fors_image_list *images)
Average collapse.
void fors_image_divide_noerr(fors_image *left, cpl_image *right)
Divide images.
void fors_image_crop(fors_image *image, int xlo, int ylo, int xhi, int yhi)
Crop image.
double fors_image_get_stdev(const fors_image *image, double *dstdev)
Get empirical stdev of data.
void fors_image_multiply_noerr(fors_image *left, const cpl_image *right)
Multiply images.
void fors_image_delete(fors_image **image)
Deallocate image and set pointer to NULL.
cpl_size fors_image_get_size_y(const fors_image *image)
Get image height.
void fors_image_divide_scalar(fors_image *image, double s, double ds)
Divide by scalar.
fors_image * fors_image_collapse_ksigma_create(const fors_image_list *images, int low, int high, int iter)
Ksigma collapse.
cpl_image * fors_imagelist_collapse_create(const cpl_imagelist *ilist)
Workaround for cpl_imagelist_collapse_create.
double fors_image_get_min(const fors_image *image)
Get min data value.
fors_image * fors_image_load(const cpl_frame *frame)
Load image.
cpl_image * fors_image_filter_max_create(const fors_image *image, int xradius, int yradius, bool use_data)
Max filter image.
void fors_image_multiply(fors_image *left, const fors_image *right)
Multiply images.
double fors_image_get_mean(const fors_image *image, double *dmean)
Get mean data value.
void fors_image_draw(fors_image *image, int type, double x, double y, int radius, double color)
Draw on image.
fors_image * fors_image_collapse_median_create(const fors_image_list *images)
Median collapse.
fors_image_list * fors_image_load_list(const cpl_frameset *frames)
Load imagelist.
double fors_utils_median_corr(int n)
median stacking correction factor
cpl_size fors_image_get_size_x(const fors_image *image)
Get image width.
void fors_image_delete_const(const fors_image **image)
Deallocate image and set pointer to NULL.
void fors_image_divide(fors_image *left, const fors_image *right)
Divide images.
cpl_image * mos_ksigma_stack(cpl_imagelist *imlist, double klow, double khigh, int kiter, cpl_image **good)
Stack images using k-sigma clipping.
float fors_tools_get_median_float(float *a, int n)
Unbiased median.
double fors_image_get_median(const fors_image *image, double *dmedian)
Get median data value.
void fors_image_exponential(fors_image *image, double b, double db)
Exponential.
double fors_image_get_error_mean(const fors_image *image, double *dmean)
Get mean of error bars.
cpl_image * mos_image_filter_median(cpl_image *image, int nx, int ny)
Convenience function for standard median filtering.
fors_image * fors_image_duplicate(const fors_image *image)
Copy constructor.
fors_image * fors_image_collapse_minmax_create(const fors_image_list *images, int low, int high)
Minmax collapse.
void fors_image_subtract_scalar(fors_image *image, double s, double ds)
Subtract scalar.
cpl_image * fors_imagelist_collapse_median_create(const cpl_imagelist *ilist)
Workaround for cpl_imagelist_collapse_median_create.
void fors_image_save(const fors_image *image, const cpl_propertylist *header, const cpl_propertylist *err_header, const char *filename)
Save image.