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 char *filename)
380 cpl_propertylist *extension_header = NULL;
381 cpl_image *sigma = NULL;
383 assure( image != NULL,
return, NULL );
385 assure( filename != NULL,
return, NULL );
387 cpl_image_save(image->data, filename, CPL_BPP_IEEE_FLOAT, header,
389 assure( !cpl_error_get_code(),
return,
390 "Cannot save product %s", filename);
392 sigma = cpl_image_power_create(image->variance, 0.5);
394 extension_header = cpl_propertylist_new();
395 cpl_propertylist_append_string(extension_header,
396 "EXTNAME",
"IMAGE.ERR");
398 cpl_image_save(sigma, filename, CPL_BPP_IEEE_FLOAT, extension_header,
400 assure( !cpl_error_get_code(),
return,
401 "Cannot save product %s", filename);
411 cpl_image_delete(var_bkg); \
412 cpl_image_delete(sigma_bkg); \
427 const char *filename_dat,
428 const char *filename_var,
431 cpl_propertylist *extension_header = NULL;
432 cpl_image *sigma_bkg = NULL;
433 cpl_image *var_bkg = NULL;
435 assure( image != NULL,
return, NULL );
437 assure( filename_dat != NULL,
return, NULL );
438 assure( filename_var != NULL,
return, NULL );
440 cpl_image_save(image->data, filename_dat, CPL_BPP_IEEE_FLOAT, header,
442 assure( !cpl_error_get_code(),
return,
443 "Cannot save product %s", filename_dat);
453 cpl_msg_info(cpl_func,
"Creating background error map");
455 bool filter_data =
false;
456 int xstep = radius/2;
463 int ystep = radius/2;
477 assure( !cpl_error_get_code(),
return,
478 "Median filtering failed");
480 sigma_bkg = cpl_image_power_create(var_bkg, 0.5);
482 cpl_image_save(sigma_bkg, filename_var,
483 CPL_BPP_IEEE_FLOAT, extension_header,
485 assure( !cpl_error_get_code(),
return,
486 "Cannot save product %s", filename_var);
501 assure( image != NULL,
return -1, NULL );
502 return cpl_image_get_size_x(image->data);
514 assure( image != NULL,
return -1, NULL );
515 return cpl_image_get_size_y(image->data);
526 assure( image != NULL,
return NULL, NULL );
528 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return NULL, NULL );
532 return cpl_image_get_data_float(image->data);
547 assure( image != NULL,
return, NULL );
549 cpl_image_abs(image->data);
566 assure( image != NULL,
return, NULL );
568 cpl_image_multiply(image->data, image->data);
573 cpl_image_multiply_scalar(image->variance, 2);
582 cpl_image_delete(temp); \
595 cpl_image *temp = NULL;
596 assure( left != NULL,
return, NULL );
597 assure( right != NULL,
return, NULL );
599 cpl_image_subtract(left->data, right->data);
602 cpl_image_add(left->variance, right->variance);
623 assure( left != NULL,
return, NULL );
624 assure( right != NULL,
return, NULL );
625 assure( cpl_image_get_size_x(left->data) == cpl_image_get_size_x(right) &&
626 cpl_image_get_size_y(left->data) == cpl_image_get_size_y(right),
628 "Incompatible data and weight image sizes: "
629 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
630 " and %"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT,
631 cpl_image_get_size_x(left->data),
632 cpl_image_get_size_y(left->data),
633 cpl_image_get_size_x(right),
634 cpl_image_get_size_y(right));
636 cpl_image_multiply(left->data, right);
637 cpl_image_multiply(left->variance, right);
638 cpl_image_multiply(left->variance, right);
664 assure( left != NULL,
return, NULL );
665 assure( right != NULL,
return, NULL );
666 assure( cpl_image_get_size_x(left->data) == cpl_image_get_size_x(right) &&
667 cpl_image_get_size_y(left->data) == cpl_image_get_size_y(right),
669 "Incompatible data and weight image sizes: "
670 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
671 " and %"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT,
672 cpl_image_get_size_x(left->data),
673 cpl_image_get_size_y(left->data),
674 cpl_image_get_size_x(right),
675 cpl_image_get_size_y(right));
678 int nx = cpl_image_get_size_x(right);
679 int ny = cpl_image_get_size_y(right);
680 float *datal = cpl_image_get_data_float(left->data);
681 float *datav = cpl_image_get_data_float(left->variance);
682 float *datar = cpl_image_get_data_float(right);
683 for (y = 0; y < ny; y++) {
684 for (x = 0; x < nx; x++) {
685 if (datar[x + nx*y] == 0) {
689 datav[x + nx*y] = FORS_IMAGE_TYPE_MAX;
694 cpl_image_divide(left->data, right);
695 cpl_image_divide(left->variance, right);
696 cpl_image_divide(left->variance, right);
704 fors_image_delete(&dupl); \
731 assure( left != NULL,
return, NULL );
732 assure( right != NULL,
return, NULL );
736 cpl_image_divide(left->data, dupl->data);
739 cpl_image_multiply(dupl->variance, left->data);
740 cpl_image_multiply(dupl->variance, left->data);
744 cpl_image_add(left->variance, dupl->variance);
748 cpl_image_divide(left->variance, dupl->data);
749 cpl_image_divide(left->variance, dupl->data);
754 int nx = cpl_image_get_size_x(left->data);
755 int ny = cpl_image_get_size_y(left->data);
756 float *datal = cpl_image_get_data_float(left->data);
757 float *datav = cpl_image_get_data_float(left->variance);
758 float *datar = cpl_image_get_data_float(right->data);
759 for (y = 0; y < ny; y++) {
760 for (x = 0; x < nx; x++) {
761 if (datar[x + nx*y] == 0) {
763 datav[x + nx*y] = FORS_IMAGE_TYPE_MAX;
775 cpl_image_delete(s22d12); \
791 cpl_image *s22d12 = NULL;
793 assure( left != NULL,
return, NULL );
794 assure( right != NULL,
return, NULL );
796 s22d12 = cpl_image_duplicate(right->variance);
797 cpl_image_multiply(s22d12, left->data);
798 cpl_image_multiply(s22d12, left->data);
800 cpl_image_multiply(left->variance, right->data);
801 cpl_image_multiply(left->variance, right->data);
802 cpl_image_add(left->variance, s22d12);
804 cpl_image_multiply(left->data, right->data);
827 assure( image != NULL,
return, NULL );
828 assure( ds <= 0,
return,
"Unsupported");
830 cpl_image_subtract_scalar(image->data, s);
852 assure( image != NULL,
return, NULL );
853 assure( s != 0,
return,
"Division by zero");
854 assure( ds <= 0,
return,
"Unsupported");
856 cpl_image_divide_scalar(image->data, s);
857 cpl_image_divide_scalar(image->variance, s*s);
878 assure( image != NULL,
return, NULL );
879 assure( ds <= 0,
return,
"Unsupported");
881 cpl_image_multiply_scalar(image->data, s);
882 cpl_image_multiply_scalar(image->variance, s*s);
890 cpl_image_delete(temp); \
907 cpl_image *temp = NULL;
909 assure( image != NULL,
return, NULL );
910 assure( b >= 0,
return,
"Negative base: %f", b);
911 assure( db <= 0,
return,
"Unsupported");
913 cpl_image_exponential(image->data, b);
917 cpl_image_multiply_scalar(image->variance, lnb*lnb);
918 cpl_image_multiply(image->variance, image->data);
919 cpl_image_multiply(image->variance, image->data);
935 assure( image != NULL,
return 0, NULL );
937 return cpl_image_get_min(image->data);
950 assure( image != NULL,
return 0, NULL );
952 return cpl_image_get_max(image->data);
966 assure( image != NULL,
return 0, NULL );
967 assure( dmean == NULL,
return 0,
"Unsupported");
969 return cpl_image_get_mean(image->data);
983 assure( image != NULL,
return 0, NULL );
984 assure( dmedian == NULL,
return 0,
"Unsupported");
986 return cpl_image_get_median(image->data);
1012 assure( image != NULL,
return, NULL );
1015 return,
"Cannot extraction region (%d, %d) - (%d, %d) of "
1016 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
" image",
1021 cpl_image *new_data = cpl_image_extract(image->data,
1024 cpl_image_delete(image->data);
1026 cpl_image* new_variance = cpl_image_extract(image->variance,
1029 cpl_image_delete(image->variance);
1031 image->data = new_data;
1032 image->variance = new_variance;
1074 const cpl_image *input = NULL;
1075 cpl_image *smooth = NULL;
1078 assure( image != NULL,
return smooth, NULL );
1079 passure( image->data != NULL,
return smooth );
1080 passure( image->variance != NULL,
return smooth );
1082 input = (use_data) ? image->data : image->variance;
1084 nx = cpl_image_get_size_x(input);
1085 ny = cpl_image_get_size_y(input);
1087 if (xstep < 1) xstep = 1;
1088 if (ystep < 1) ystep = 1;
1090 assure( 1 <= xstart && xstart <= xend && xend <= nx &&
1091 1 <= ystart && ystart <= yend && yend <= ny,
return smooth,
1092 "Illegal region (%d, %d) - (%d, %d) of %dx%d image",
1097 smooth = cpl_image_duplicate(input);
1100 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return smooth, NULL );
1102 const float *input_data = cpl_image_get_data_float_const(input);
1103 float *smooth_data = cpl_image_get_data_float(smooth);
1104 float *data = cpl_malloc((2*yradius + 1)*(2*xradius + 1)*
sizeof(*data));
1107 for (y = ystart; y < yend; y++) {
1114 int ylo = y - (yradius/ystep) * ystep;
1115 int yhi = y + (yradius/ystep) * ystep;
1117 while (ylo < ystart) ylo += ystep;
1118 while (yhi > yend ) yhi -= ystep;
1121 for (x = xstart; x < xend; x++) {
1122 int xlo = x - (xradius/xstep) * xstep;
1123 int xhi = x + (xradius/xstep) * xstep;
1125 while (xlo < xstart) xlo += xstep;
1126 while (xhi > xend ) xhi -= xstep;
1131 for (j = ylo; j <= yhi; j += ystep) {
1132 for (i = xlo; i <= xhi; i += xstep) {
1133 data[k++] = input_data[ (i-1) + (j-1)*nx ];
1138 smooth_data[ (x-1) + (y-1)*nx ] =
1150 cpl_image_delete(input); \
1153 fors_image_flat_fit_create(
fors_image *image,
1158 cpl_image *temp = NULL;
1159 cpl_image *input = NULL;
1160 cpl_image *smooth = NULL;
1163 assure( image != NULL,
return smooth, NULL );
1164 passure( image->data != NULL,
return smooth );
1165 assure( step > 0,
return smooth, NULL );
1166 assure( degree >= 0,
return smooth, NULL );
1171 nx = cpl_image_get_size_x(temp);
1172 ny = cpl_image_get_size_y(temp);
1178 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return smooth, NULL );
1186 const float *input_data = cpl_image_get_data_float_const(input);
1194 for (y = 0; y < ny; y += step) {
1196 for (x = 0; x < nx; x += step, pos += step) {
1197 if (input_data[pos] > level) {
1203 if (count < (degree+1)*(degree+2)) {
1204 step = sqrt((nx*nx)/((degree+1)*(degree+2))) / 2;
1207 cpl_msg_error(cpl_func,
"Flat field image too small (%dx%d). "
1208 "Please provide a smaller resampling step (a good "
1209 "value would be %d)", nx, ny, step);
1210 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1220 cpl_bivector *positions = cpl_bivector_new(count);
1221 double *xpos = cpl_bivector_get_x_data(positions);
1222 double *ypos = cpl_bivector_get_y_data(positions);
1223 cpl_vector *fluxes = cpl_vector_new(count);
1224 double *flux = cpl_vector_get_data(fluxes);
1227 for (y = 0; y < ny; y += step) {
1229 for (x = 0; x < nx; x += step, pos += step) {
1230 if (input_data[pos] > level) {
1233 flux[count] = input_data[pos];
1239 cpl_image_delete(input); input = NULL;
1246 cpl_polynomial *model = cpl_polynomial_fit_2d_create(positions,
1251 cpl_bivector_delete(positions);
1252 cpl_vector_delete(fluxes);
1254 smooth = cpl_image_new(nx, ny, FORS_IMAGE_TYPE);
1255 float *smooth_data = cpl_image_get_data_float(smooth);
1257 cpl_vector *point = cpl_vector_new(2);
1258 double *dpoint = cpl_vector_get_data(point);
1260 for (y = 0; y < ny; y++) {
1263 for (x = 0; x < nx; x++, pos++) {
1265 smooth_data[pos] = cpl_polynomial_eval(model, point);
1269 cpl_polynomial_delete(model);
1270 cpl_vector_delete(point);
1301 const cpl_image *input = NULL;
1302 cpl_image *hmaxima = NULL;
1303 cpl_image *maxima = NULL;
1306 assure( image != NULL,
return maxima, NULL );
1307 passure( image->data != NULL,
return maxima );
1308 passure( image->variance != NULL,
return maxima );
1310 input = (use_data) ? image->data : image->variance;
1312 nx = cpl_image_get_size_x(input);
1313 ny = cpl_image_get_size_y(input);
1319 hmaxima = cpl_image_duplicate(input);
1322 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return maxima, NULL );
1324 float *input_data = (
float *)cpl_image_get_data_float_const(input);
1325 float *maxima_data = cpl_image_get_data_float(hmaxima);
1328 for (y = 0; y < ny; y++) {
1329 const float *irow = input_data + y * nx;
1330 float *orow = maxima_data + y * nx;
1331 max_filter(irow, orow, nx, 2*xradius+1);
1334 cpl_image_turn(hmaxima, 1);
1340 maxima = cpl_image_duplicate(hmaxima);
1341 input_data = cpl_image_get_data_float(hmaxima);
1342 maxima_data = cpl_image_get_data_float(maxima);
1349 for (x = 0; x < nx; x++) {
1350 const float *irow = input_data + x * ny;
1351 float *orow = maxima_data + x * ny;
1352 max_filter(irow, orow, ny, 2*yradius+1);
1355 cpl_image_delete(hmaxima);
1357 cpl_image_turn(maxima, -1);
1373 assure( image != NULL,
return 0, NULL );
1374 assure( dstdev == NULL,
return 0,
"Unsupported");
1376 return cpl_image_get_stdev(image->data);
1381 cpl_mask_delete(rejected); \
1382 cpl_image_delete(im); \
1396 cpl_mask *rejected = NULL;
1397 cpl_image *im = NULL;
1399 assure( image != NULL,
return 0, NULL );
1400 assure( cut > 0,
return 0,
"Illegal cut: %f", cut );
1401 assure( dstdev == NULL,
return 0,
"Unsupported");
1405 im = cpl_image_duplicate(image->data);
1406 cpl_image_subtract_scalar(im, median);
1407 cpl_image_power(im, 2);
1410 rejected = cpl_mask_threshold_image_create(image->data,
1413 cpl_mask_not(rejected);
1414 cpl_image_reject_from_mask(im, rejected);
1416 double robust_stdev = sqrt(cpl_image_get_mean(im));
1419 return robust_stdev;
1439 assure( image != NULL,
return 0, NULL );
1440 assure( dmean == NULL,
return 0,
"Unsupported");
1442 avg = cpl_image_get_mean(image->variance);
1445 assure( avg >= 0,
return -1,
"Average variance is %f", avg);
1454 cpl_imagelist_delete(datlist); \
1455 cpl_imagelist_delete(varlist); \
1469 cpl_imagelist *datlist = NULL;
1470 cpl_imagelist *varlist = NULL;
1471 cpl_image *data = NULL;
1472 cpl_image *variance = NULL;
1476 assure( images != NULL,
return NULL, NULL );
1477 assure( fors_image_list_size(images) > 0,
return NULL,
1478 "Cannot stack zero images");
1480 i = fors_image_list_first_const(images);
1482 datlist = cpl_imagelist_new();
1483 varlist = cpl_imagelist_new();
1488 cpl_imagelist_set(datlist,
1489 cpl_image_duplicate(i->data),
1490 cpl_imagelist_get_size(datlist));
1491 cpl_imagelist_set(varlist,
1492 cpl_image_duplicate(i->variance),
1493 cpl_imagelist_get_size(varlist));
1494 i = fors_image_list_next_const(images);
1498 #ifdef CPL_IS_NOT_CRAP
1499 data = cpl_imagelist_collapse_create(datlist);
1501 variance = cpl_imagelist_collapse_create(varlist);
1508 cpl_image_divide_scalar(variance, N);
1518 cpl_imagelist_delete(datlist); \
1519 cpl_imagelist_delete(varlist); \
1536 cpl_imagelist *datlist = NULL;
1537 cpl_imagelist *varlist = NULL;
1538 cpl_image *data = NULL;
1539 cpl_image *variance = NULL;
1543 assure( images != NULL,
return NULL, NULL );
1544 assure( fors_image_list_size(images) > low + high,
return NULL,
1545 "Cannot reject more images than there are");
1546 assure( low*high >= 0 && low+high > 0,
return NULL,
1547 "Invalid minmax rejection criteria");
1549 i = fors_image_list_first_const(images);
1551 datlist = cpl_imagelist_new();
1552 varlist = cpl_imagelist_new();
1557 cpl_imagelist_set(datlist,
1558 cpl_image_duplicate(i->data),
1559 cpl_imagelist_get_size(datlist));
1560 cpl_imagelist_set(varlist,
1561 cpl_image_duplicate(i->variance),
1562 cpl_imagelist_get_size(varlist));
1563 i = fors_image_list_next_const(images);
1567 data = cpl_imagelist_collapse_minmax_create(datlist, low, high);
1568 variance = cpl_imagelist_collapse_minmax_create(varlist, low, high);
1570 cpl_image_divide_scalar(variance, N);
1590 int low,
int high,
int iter)
1592 cpl_imagelist *datlist = NULL;
1593 cpl_imagelist *varlist = NULL;
1594 cpl_image *data = NULL;
1595 cpl_image *variance = NULL;
1596 cpl_image *ngood = NULL;
1599 assure( images != NULL,
return NULL, NULL );
1601 i = fors_image_list_first_const(images);
1603 datlist = cpl_imagelist_new();
1604 varlist = cpl_imagelist_new();
1609 cpl_imagelist_set(datlist,
1610 cpl_image_duplicate(i->data),
1611 cpl_imagelist_get_size(datlist));
1612 cpl_imagelist_set(varlist,
1613 cpl_image_duplicate(i->variance),
1614 cpl_imagelist_get_size(varlist));
1615 i = fors_image_list_next_const(images);
1619 variance = cpl_imagelist_collapse_create(varlist);
1621 cpl_image_divide(variance, ngood);
1623 cpl_image_delete(ngood);
1643 cpl_imagelist *datlist = NULL;
1644 cpl_imagelist *varlist = NULL;
1645 cpl_image *data = NULL;
1646 cpl_image *variance = NULL;
1650 assure( images != NULL,
return NULL, NULL );
1651 assure( fors_image_list_size(images) > 0,
return NULL,
1652 "Cannot stack zero images");
1654 i = fors_image_list_first_const(images);
1656 datlist = cpl_imagelist_new();
1657 varlist = cpl_imagelist_new();
1660 cpl_imagelist_set(datlist,
1661 cpl_image_duplicate(i->data),
1662 cpl_imagelist_get_size(datlist));
1663 cpl_imagelist_set(varlist,
1664 cpl_image_duplicate(i->variance),
1665 cpl_imagelist_get_size(varlist));
1667 i = fors_image_list_next_const(images);
1671 #ifdef CPL_IS_NOT_CRAP
1672 data = cpl_imagelist_collapse_median_create(datlist);
1674 variance = cpl_imagelist_collapse_create(varlist);
1681 cpl_image_divide_scalar(variance, N);
1683 cpl_image_multiply_scalar(variance,
1712 int radius,
double color)
1714 assure( image != NULL,
return, NULL );
1716 assure( type == 0 || type == 1 || type == 2,
1717 return ,
"Unsupported type %d", type);
1719 assure( radius > 0,
return, NULL );
1723 for (i = 0; i < 360; i++) {
1726 int px = x + radius*cos(i/(2*M_PI));
1727 int py = y + radius*sin(i/(2*M_PI));
1729 if (1 <= px && px <= cpl_image_get_size_x(image->data) &&
1730 1 <= py && py <= cpl_image_get_size_y(image->data)) {
1731 cpl_image_set(image->data, px, py, color);
1732 cpl_image_set(image->variance, px, py, color > 0 ? color : 0);
1739 for (i = -radius; i <= radius; i++) {
1752 if (1 <= px && px <= cpl_image_get_size_x(image->data) &&
1753 1 <= py && py <= cpl_image_get_size_y(image->data)) {
1754 cpl_image_set(image->data , px, py, color);
1755 cpl_image_set(image->variance, px, py, color > 0 ? color : 0);
1763 hdrl_imagelist * fors_image_list_to_hdrl(
const fors_image_list * imalist)
1766 hdrl_imagelist * images_hdrl = hdrl_imagelist_new();
1767 const fors_image * target = fors_image_list_first_const(imalist);
1768 for(i = 0 ; i < fors_image_list_size(imalist); ++i)
1770 const cpl_image * ima_data = target->data;
1771 cpl_image * ima_error = cpl_image_power_create(target->variance, 0.5);
1772 cpl_mask * old_bpm = cpl_image_set_bpm(ima_error,
1773 cpl_mask_duplicate(cpl_image_get_bpm_const(ima_data)));
1774 cpl_mask_delete(old_bpm);
1775 hdrl_image * ima_hdrl = hdrl_image_create(ima_data, ima_error);
1776 hdrl_imagelist_set(images_hdrl, ima_hdrl,
1777 hdrl_imagelist_get_size(images_hdrl));
1778 target = fors_image_list_next_const(imalist);
1784 fors_image * fors_image_from_hdrl(
const hdrl_image * image)
1786 const cpl_image * data = hdrl_image_get_image_const(image);
1787 cpl_image * variance = cpl_image_power_create
1788 (hdrl_image_get_image_const(image), 2);
1796 #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.
void fors_image_save(const fors_image *image, const cpl_propertylist *header, const char *filename)
Save image.
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.