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 *)
294 cpl_image *data = NULL;
295 cpl_image *variance = NULL;
296 const char *filename;
300 assure( frame != NULL,
return image, NULL );
302 filename = cpl_frame_get_filename(frame);
303 assure( filename != NULL,
return image,
304 "NULL filename received");
306 cpl_msg_info(cpl_func,
"Loading %s: %s",
308 (cpl_frame_get_tag(frame) != NULL) ?
309 cpl_frame_get_tag(frame) :
"NULL",
313 data = cpl_image_load(filename,
314 FORS_IMAGE_TYPE, plane, extension);
316 assure( data != NULL,
return image,
317 "Could not load image from %s extension %d",
318 filename, extension);
322 if (cpl_frame_get_nextensions(frame) == 0) {
325 variance = cpl_image_new(
326 cpl_image_get_size_x(data),
327 cpl_image_get_size_y(data),
336 variance = cpl_image_load(filename,
337 FORS_IMAGE_TYPE, plane, extension);
339 assure( variance != NULL,
return image,
340 "Could not load image from %s extension %d",
341 filename, extension);
343 cpl_image_power(variance, 2);
345 assure( cpl_image_get_min(variance) >= 0,
346 cpl_image_delete(variance);
return image,
347 "Illegal minimum variance: %g",
348 cpl_image_get_min(variance));
362 cpl_image_delete(sigma); \
363 cpl_propertylist_delete(extension_header); \
376 const cpl_propertylist *err_header,
377 const char *filename)
379 cpl_propertylist *extension_header = NULL;
380 cpl_image *sigma = NULL;
382 assure( image != NULL,
return, NULL );
384 assure( filename != NULL,
return, NULL );
386 cpl_image_save(image->data, filename, CPL_BPP_IEEE_FLOAT, header,
388 assure( !cpl_error_get_code(),
return,
389 "Cannot save product %s", filename);
391 sigma = cpl_image_power_create(image->variance, 0.5);
393 if(err_header != NULL)
394 extension_header = cpl_propertylist_duplicate(err_header);
396 extension_header = cpl_propertylist_new();
397 cpl_propertylist_append_string(extension_header,
398 "EXTNAME",
"IMAGE.ERR");
400 cpl_image_save(sigma, filename, CPL_BPP_IEEE_FLOAT, extension_header,
402 assure( !cpl_error_get_code(),
return,
403 "Cannot save product %s", filename);
413 cpl_image_delete(var_bkg); \
414 cpl_image_delete(sigma_bkg); \
429 const char *filename_dat,
430 const char *filename_var,
433 cpl_propertylist *extension_header = NULL;
434 cpl_image *sigma_bkg = NULL;
435 cpl_image *var_bkg = NULL;
437 assure( image != NULL,
return, NULL );
439 assure( filename_dat != NULL,
return, NULL );
440 assure( filename_var != NULL,
return, NULL );
442 cpl_image_save(image->data, filename_dat, CPL_BPP_IEEE_FLOAT, header,
444 assure( !cpl_error_get_code(),
return,
445 "Cannot save product %s", filename_dat);
455 cpl_msg_info(cpl_func,
"Creating background error map");
457 bool filter_data =
false;
458 int xstep = radius/2;
465 int ystep = radius/2;
479 assure( !cpl_error_get_code(),
return,
480 "Median filtering failed");
482 sigma_bkg = cpl_image_power_create(var_bkg, 0.5);
484 cpl_image_save(sigma_bkg, filename_var,
485 CPL_BPP_IEEE_FLOAT, extension_header,
487 assure( !cpl_error_get_code(),
return,
488 "Cannot save product %s", filename_var);
503 assure( image != NULL,
return -1, NULL );
504 return cpl_image_get_size_x(image->data);
516 assure( image != NULL,
return -1, NULL );
517 return cpl_image_get_size_y(image->data);
528 assure( image != NULL,
return NULL, NULL );
530 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return NULL, NULL );
534 return cpl_image_get_data_float(image->data);
549 assure( image != NULL,
return, NULL );
551 cpl_image_abs(image->data);
568 assure( image != NULL,
return, NULL );
570 cpl_image_multiply(image->data, image->data);
575 cpl_image_multiply_scalar(image->variance, 2);
584 cpl_image_delete(temp); \
597 cpl_image *temp = NULL;
598 assure( left != NULL,
return, NULL );
599 assure( right != NULL,
return, NULL );
601 cpl_image_subtract(left->data, right->data);
604 cpl_image_add(left->variance, right->variance);
625 assure( left != NULL,
return, NULL );
626 assure( right != NULL,
return, NULL );
627 assure( cpl_image_get_size_x(left->data) == cpl_image_get_size_x(right) &&
628 cpl_image_get_size_y(left->data) == cpl_image_get_size_y(right),
630 "Incompatible data and weight image sizes: "
631 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
632 " and %"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT,
633 cpl_image_get_size_x(left->data),
634 cpl_image_get_size_y(left->data),
635 cpl_image_get_size_x(right),
636 cpl_image_get_size_y(right));
638 cpl_image_multiply(left->data, right);
639 cpl_image_multiply(left->variance, right);
640 cpl_image_multiply(left->variance, right);
666 assure( left != NULL,
return, NULL );
667 assure( right != NULL,
return, NULL );
668 assure( cpl_image_get_size_x(left->data) == cpl_image_get_size_x(right) &&
669 cpl_image_get_size_y(left->data) == cpl_image_get_size_y(right),
671 "Incompatible data and weight image sizes: "
672 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
673 " and %"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT,
674 cpl_image_get_size_x(left->data),
675 cpl_image_get_size_y(left->data),
676 cpl_image_get_size_x(right),
677 cpl_image_get_size_y(right));
680 int nx = cpl_image_get_size_x(right);
681 int ny = cpl_image_get_size_y(right);
682 float *datal = cpl_image_get_data_float(left->data);
683 float *datav = cpl_image_get_data_float(left->variance);
684 float *datar = cpl_image_get_data_float(right);
685 for (y = 0; y < ny; y++) {
686 for (x = 0; x < nx; x++) {
687 if (datar[x + nx*y] == 0) {
691 datav[x + nx*y] = FORS_IMAGE_TYPE_MAX;
696 cpl_image_divide(left->data, right);
697 cpl_image_divide(left->variance, right);
698 cpl_image_divide(left->variance, right);
706 fors_image_delete(&dupl); \
733 assure( left != NULL,
return, NULL );
734 assure( right != NULL,
return, NULL );
738 cpl_image_divide(left->data, dupl->data);
741 cpl_image_multiply(dupl->variance, left->data);
742 cpl_image_multiply(dupl->variance, left->data);
746 cpl_image_add(left->variance, dupl->variance);
750 cpl_image_divide(left->variance, dupl->data);
751 cpl_image_divide(left->variance, dupl->data);
756 int nx = cpl_image_get_size_x(left->data);
757 int ny = cpl_image_get_size_y(left->data);
758 float *datal = cpl_image_get_data_float(left->data);
759 float *datav = cpl_image_get_data_float(left->variance);
760 float *datar = cpl_image_get_data_float(right->data);
761 for (y = 0; y < ny; y++) {
762 for (x = 0; x < nx; x++) {
763 if (datar[x + nx*y] == 0) {
765 datav[x + nx*y] = FORS_IMAGE_TYPE_MAX;
777 cpl_image_delete(s22d12); \
793 cpl_image *s22d12 = NULL;
795 assure( left != NULL,
return, NULL );
796 assure( right != NULL,
return, NULL );
798 s22d12 = cpl_image_duplicate(right->variance);
799 cpl_image_multiply(s22d12, left->data);
800 cpl_image_multiply(s22d12, left->data);
802 cpl_image_multiply(left->variance, right->data);
803 cpl_image_multiply(left->variance, right->data);
804 cpl_image_add(left->variance, s22d12);
806 cpl_image_multiply(left->data, right->data);
829 assure( image != NULL,
return, NULL );
830 assure( ds <= 0,
return,
"Unsupported");
832 cpl_image_subtract_scalar(image->data, s);
854 assure( image != NULL,
return, NULL );
855 assure( s != 0,
return,
"Division by zero");
856 assure( ds <= 0,
return,
"Unsupported");
858 cpl_image_divide_scalar(image->data, s);
859 cpl_image_divide_scalar(image->variance, s*s);
880 assure( image != NULL,
return, NULL );
881 assure( ds <= 0,
return,
"Unsupported");
883 cpl_image_multiply_scalar(image->data, s);
884 cpl_image_multiply_scalar(image->variance, s*s);
892 cpl_image_delete(temp); \
909 cpl_image *temp = NULL;
911 assure( image != NULL,
return, NULL );
912 assure( b >= 0,
return,
"Negative base: %f", b);
913 assure( db <= 0,
return,
"Unsupported");
915 cpl_image_exponential(image->data, b);
919 cpl_image_multiply_scalar(image->variance, lnb*lnb);
920 cpl_image_multiply(image->variance, image->data);
921 cpl_image_multiply(image->variance, image->data);
937 assure( image != NULL,
return 0, NULL );
939 return cpl_image_get_min(image->data);
952 assure( image != NULL,
return 0, NULL );
954 return cpl_image_get_max(image->data);
968 assure( image != NULL,
return 0, NULL );
969 assure( dmean == NULL,
return 0,
"Unsupported");
971 return cpl_image_get_mean(image->data);
985 assure( image != NULL,
return 0, NULL );
986 assure( dmedian == NULL,
return 0,
"Unsupported");
988 return cpl_image_get_median(image->data);
1014 assure( image != NULL,
return, NULL );
1017 return,
"Cannot extraction region (%d, %d) - (%d, %d) of "
1018 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
" image",
1023 cpl_image *new_data = cpl_image_extract(image->data,
1026 cpl_image_delete(image->data);
1028 cpl_image* new_variance = cpl_image_extract(image->variance,
1031 cpl_image_delete(image->variance);
1033 image->data = new_data;
1034 image->variance = new_variance;
1076 const cpl_image *input = NULL;
1077 cpl_image *smooth = NULL;
1080 assure( image != NULL,
return smooth, NULL );
1081 passure( image->data != NULL,
return smooth );
1082 passure( image->variance != NULL,
return smooth );
1084 input = (use_data) ? image->data : image->variance;
1086 nx = cpl_image_get_size_x(input);
1087 ny = cpl_image_get_size_y(input);
1089 if (xstep < 1) xstep = 1;
1090 if (ystep < 1) ystep = 1;
1092 assure( 1 <= xstart && xstart <= xend && xend <= nx &&
1093 1 <= ystart && ystart <= yend && yend <= ny,
return smooth,
1094 "Illegal region (%d, %d) - (%d, %d) of %dx%d image",
1099 smooth = cpl_image_duplicate(input);
1102 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return smooth, NULL );
1104 const float *input_data = cpl_image_get_data_float_const(input);
1105 float *smooth_data = cpl_image_get_data_float(smooth);
1106 float *data = cpl_malloc((2*yradius + 1)*(2*xradius + 1)*
sizeof(*data));
1109 for (y = ystart; y < yend; y++) {
1116 int ylo = y - (yradius/ystep) * ystep;
1117 int yhi = y + (yradius/ystep) * ystep;
1119 while (ylo < ystart) ylo += ystep;
1120 while (yhi > yend ) yhi -= ystep;
1123 for (x = xstart; x < xend; x++) {
1124 int xlo = x - (xradius/xstep) * xstep;
1125 int xhi = x + (xradius/xstep) * xstep;
1127 while (xlo < xstart) xlo += xstep;
1128 while (xhi > xend ) xhi -= xstep;
1133 for (j = ylo; j <= yhi; j += ystep) {
1134 for (i = xlo; i <= xhi; i += xstep) {
1135 data[k++] = input_data[ (i-1) + (j-1)*nx ];
1140 smooth_data[ (x-1) + (y-1)*nx ] =
1152 cpl_image_delete(input); \
1155 fors_image_flat_fit_create(
fors_image *image,
1160 cpl_image *temp = NULL;
1161 cpl_image *input = NULL;
1162 cpl_image *smooth = NULL;
1165 assure( image != NULL,
return smooth, NULL );
1166 passure( image->data != NULL,
return smooth );
1167 assure( step > 0,
return smooth, NULL );
1168 assure( degree >= 0,
return smooth, NULL );
1173 nx = cpl_image_get_size_x(temp);
1174 ny = cpl_image_get_size_y(temp);
1180 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return smooth, NULL );
1188 const float *input_data = cpl_image_get_data_float_const(input);
1196 for (y = 0; y < ny; y += step) {
1198 for (x = 0; x < nx; x += step, pos += step) {
1199 if (input_data[pos] > level) {
1205 if (count < (degree+1)*(degree+2)) {
1206 step = sqrt((nx*nx)/((degree+1)*(degree+2))) / 2;
1209 cpl_msg_error(cpl_func,
"Flat field image too small (%dx%d). "
1210 "Please provide a smaller resampling step (a good "
1211 "value would be %d)", nx, ny, step);
1212 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1222 cpl_bivector *positions = cpl_bivector_new(count);
1223 double *xpos = cpl_bivector_get_x_data(positions);
1224 double *ypos = cpl_bivector_get_y_data(positions);
1225 cpl_vector *fluxes = cpl_vector_new(count);
1226 double *flux = cpl_vector_get_data(fluxes);
1229 for (y = 0; y < ny; y += step) {
1231 for (x = 0; x < nx; x += step, pos += step) {
1232 if (input_data[pos] > level) {
1235 flux[count] = input_data[pos];
1241 cpl_image_delete(input); input = NULL;
1248 cpl_polynomial *model = cpl_polynomial_fit_2d_create(positions,
1253 cpl_bivector_delete(positions);
1254 cpl_vector_delete(fluxes);
1256 smooth = cpl_image_new(nx, ny, FORS_IMAGE_TYPE);
1257 float *smooth_data = cpl_image_get_data_float(smooth);
1259 cpl_vector *point = cpl_vector_new(2);
1260 double *dpoint = cpl_vector_get_data(point);
1262 for (y = 0; y < ny; y++) {
1265 for (x = 0; x < nx; x++, pos++) {
1267 smooth_data[pos] = cpl_polynomial_eval(model, point);
1271 cpl_polynomial_delete(model);
1272 cpl_vector_delete(point);
1303 const cpl_image *input = NULL;
1304 cpl_image *hmaxima = NULL;
1305 cpl_image *maxima = NULL;
1308 assure( image != NULL,
return maxima, NULL );
1309 passure( image->data != NULL,
return maxima );
1310 passure( image->variance != NULL,
return maxima );
1312 input = (use_data) ? image->data : image->variance;
1314 nx = cpl_image_get_size_x(input);
1315 ny = cpl_image_get_size_y(input);
1321 hmaxima = cpl_image_duplicate(input);
1324 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return maxima, NULL );
1326 float *input_data = (
float *)cpl_image_get_data_float_const(input);
1327 float *maxima_data = cpl_image_get_data_float(hmaxima);
1330 for (y = 0; y < ny; y++) {
1331 const float *irow = input_data + y * nx;
1332 float *orow = maxima_data + y * nx;
1333 max_filter(irow, orow, nx, 2*xradius+1);
1336 cpl_image_turn(hmaxima, 1);
1342 maxima = cpl_image_duplicate(hmaxima);
1343 input_data = cpl_image_get_data_float(hmaxima);
1344 maxima_data = cpl_image_get_data_float(maxima);
1351 for (x = 0; x < nx; x++) {
1352 const float *irow = input_data + x * ny;
1353 float *orow = maxima_data + x * ny;
1354 max_filter(irow, orow, ny, 2*yradius+1);
1357 cpl_image_delete(hmaxima);
1359 cpl_image_turn(maxima, -1);
1375 assure( image != NULL,
return 0, NULL );
1376 assure( dstdev == NULL,
return 0,
"Unsupported");
1378 return cpl_image_get_stdev(image->data);
1383 cpl_mask_delete(rejected); \
1384 cpl_image_delete(im); \
1398 cpl_mask *rejected = NULL;
1399 cpl_image *im = NULL;
1401 assure( image != NULL,
return 0, NULL );
1402 assure( cut > 0,
return 0,
"Illegal cut: %f", cut );
1403 assure( dstdev == NULL,
return 0,
"Unsupported");
1407 im = cpl_image_duplicate(image->data);
1408 cpl_image_subtract_scalar(im, median);
1409 cpl_image_power(im, 2);
1412 rejected = cpl_mask_threshold_image_create(image->data,
1415 cpl_mask_not(rejected);
1416 cpl_image_reject_from_mask(im, rejected);
1418 double robust_stdev = sqrt(cpl_image_get_mean(im));
1421 return robust_stdev;
1441 assure( image != NULL,
return 0, NULL );
1442 assure( dmean == NULL,
return 0,
"Unsupported");
1444 avg = cpl_image_get_mean(image->variance);
1447 assure( avg >= 0,
return -1,
"Average variance is %f", avg);
1456 cpl_imagelist_delete(datlist); \
1457 cpl_imagelist_delete(varlist); \
1471 cpl_imagelist *datlist = NULL;
1472 cpl_imagelist *varlist = NULL;
1473 cpl_image *data = NULL;
1474 cpl_image *variance = NULL;
1478 assure( images != NULL,
return NULL, NULL );
1479 assure( fors_image_list_size(images) > 0,
return NULL,
1480 "Cannot stack zero images");
1482 i = fors_image_list_first_const(images);
1484 datlist = cpl_imagelist_new();
1485 varlist = cpl_imagelist_new();
1490 cpl_imagelist_set(datlist,
1491 cpl_image_duplicate(i->data),
1492 cpl_imagelist_get_size(datlist));
1493 cpl_imagelist_set(varlist,
1494 cpl_image_duplicate(i->variance),
1495 cpl_imagelist_get_size(varlist));
1496 i = fors_image_list_next_const(images);
1500 #ifdef CPL_IS_NOT_CRAP
1501 data = cpl_imagelist_collapse_create(datlist);
1503 variance = cpl_imagelist_collapse_create(varlist);
1510 cpl_image_divide_scalar(variance, N);
1520 cpl_imagelist_delete(datlist); \
1521 cpl_imagelist_delete(varlist); \
1538 cpl_imagelist *datlist = NULL;
1539 cpl_imagelist *varlist = NULL;
1540 cpl_image *data = NULL;
1541 cpl_image *variance = NULL;
1545 assure( images != NULL,
return NULL, NULL );
1546 assure( fors_image_list_size(images) > low + high,
return NULL,
1547 "Cannot reject more images than there are");
1548 assure( low*high >= 0 && low+high > 0,
return NULL,
1549 "Invalid minmax rejection criteria");
1551 i = fors_image_list_first_const(images);
1553 datlist = cpl_imagelist_new();
1554 varlist = cpl_imagelist_new();
1559 cpl_imagelist_set(datlist,
1560 cpl_image_duplicate(i->data),
1561 cpl_imagelist_get_size(datlist));
1562 cpl_imagelist_set(varlist,
1563 cpl_image_duplicate(i->variance),
1564 cpl_imagelist_get_size(varlist));
1565 i = fors_image_list_next_const(images);
1569 data = cpl_imagelist_collapse_minmax_create(datlist, low, high);
1570 variance = cpl_imagelist_collapse_minmax_create(varlist, low, high);
1572 cpl_image_divide_scalar(variance, N);
1592 int low,
int high,
int iter)
1594 cpl_imagelist *datlist = NULL;
1595 cpl_imagelist *varlist = NULL;
1596 cpl_image *data = NULL;
1597 cpl_image *variance = NULL;
1598 cpl_image *ngood = NULL;
1601 assure( images != NULL,
return NULL, NULL );
1603 i = fors_image_list_first_const(images);
1605 datlist = cpl_imagelist_new();
1606 varlist = cpl_imagelist_new();
1611 cpl_imagelist_set(datlist,
1612 cpl_image_duplicate(i->data),
1613 cpl_imagelist_get_size(datlist));
1614 cpl_imagelist_set(varlist,
1615 cpl_image_duplicate(i->variance),
1616 cpl_imagelist_get_size(varlist));
1617 i = fors_image_list_next_const(images);
1621 variance = cpl_imagelist_collapse_create(varlist);
1623 cpl_image_divide(variance, ngood);
1625 cpl_image_delete(ngood);
1645 cpl_imagelist *datlist = NULL;
1646 cpl_imagelist *varlist = NULL;
1647 cpl_image *data = NULL;
1648 cpl_image *variance = NULL;
1652 assure( images != NULL,
return NULL, NULL );
1653 assure( fors_image_list_size(images) > 0,
return NULL,
1654 "Cannot stack zero images");
1656 i = fors_image_list_first_const(images);
1658 datlist = cpl_imagelist_new();
1659 varlist = cpl_imagelist_new();
1662 cpl_imagelist_set(datlist,
1663 cpl_image_duplicate(i->data),
1664 cpl_imagelist_get_size(datlist));
1665 cpl_imagelist_set(varlist,
1666 cpl_image_duplicate(i->variance),
1667 cpl_imagelist_get_size(varlist));
1669 i = fors_image_list_next_const(images);
1673 #ifdef CPL_IS_NOT_CRAP
1674 data = cpl_imagelist_collapse_median_create(datlist);
1676 variance = cpl_imagelist_collapse_create(varlist);
1683 cpl_image_divide_scalar(variance, N);
1685 cpl_image_multiply_scalar(variance,
1714 int radius,
double color)
1716 assure( image != NULL,
return, NULL );
1718 assure( type == 0 || type == 1 || type == 2,
1719 return ,
"Unsupported type %d", type);
1721 assure( radius > 0,
return, NULL );
1725 for (i = 0; i < 360; i++) {
1728 int px = x + radius*cos(i/(2*M_PI));
1729 int py = y + radius*sin(i/(2*M_PI));
1731 if (1 <= px && px <= cpl_image_get_size_x(image->data) &&
1732 1 <= py && py <= cpl_image_get_size_y(image->data)) {
1733 cpl_image_set(image->data, px, py, color);
1734 cpl_image_set(image->variance, px, py, color > 0 ? color : 0);
1741 for (i = -radius; i <= radius; i++) {
1754 if (1 <= px && px <= cpl_image_get_size_x(image->data) &&
1755 1 <= py && py <= cpl_image_get_size_y(image->data)) {
1756 cpl_image_set(image->data , px, py, color);
1757 cpl_image_set(image->variance, px, py, color > 0 ? color : 0);
1765 hdrl_imagelist * fors_image_list_to_hdrl(
const fors_image_list * imalist)
1768 hdrl_imagelist * images_hdrl = hdrl_imagelist_new();
1769 const fors_image * target = fors_image_list_first_const(imalist);
1770 for(i = 0 ; i < fors_image_list_size(imalist); ++i)
1772 const cpl_image * ima_data = target->data;
1773 cpl_image * ima_error = cpl_image_power_create(target->variance, 0.5);
1774 cpl_mask * old_bpm = cpl_image_set_bpm(ima_error,
1775 cpl_mask_duplicate(cpl_image_get_bpm_const(ima_data)));
1776 cpl_mask_delete(old_bpm);
1777 hdrl_image * ima_hdrl = hdrl_image_create(ima_data, ima_error);
1778 hdrl_imagelist_set(images_hdrl, ima_hdrl,
1779 hdrl_imagelist_get_size(images_hdrl));
1780 target = fors_image_list_next_const(imalist);
1781 cpl_image_delete(ima_error);
1787 fors_image * fors_image_from_hdrl(
const hdrl_image * image)
1789 const cpl_image * data = hdrl_image_get_image_const(image);
1790 cpl_image * variance = cpl_image_power_create
1791 (hdrl_image_get_error_const(image), 2);
1799 #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.