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 %f",
131 cpl_image_get_min(variance));
133 image = cpl_malloc(
sizeof(*image));
136 image->variance = variance;
151 assure( image != NULL,
return NULL, NULL );
154 cpl_image_duplicate(image->variance));
164 if (image && *image) {
165 cpl_image_delete((*image)->data);
166 cpl_image_delete((*image)->variance);
167 cpl_free(*image); *image = NULL;
191 fors_image_dump(
const fors_image *image, FILE *file)
194 fprintf(file,
"Null image\n");
199 fprintf(file,
"Data:\n");
200 stats = cpl_stats_new_from_image(image->data, CPL_STATS_ALL);
201 cpl_stats_dump(stats, CPL_STATS_ALL, file);
202 cpl_stats_delete(stats);
204 fprintf(file,
"Variance:\n");
205 stats = cpl_stats_new_from_image(image->variance, CPL_STATS_ALL);
206 cpl_stats_dump(stats, CPL_STATS_ALL, file);
207 cpl_stats_delete(stats);
217 double_list_delete(&sat_percent, double_delete); \
236 fors_image_list *ilist = fors_image_list_new();
237 double_list *sat_percent = double_list_new();
239 assure( frames != NULL,
return ilist, NULL );
240 assure( !cpl_frameset_is_empty(frames),
return ilist,
"Empty frameset");
245 for (
int i =0; i< cpl_frameset_get_size(frames); i ++)
247 f = cpl_frameset_get_position_const(frames, i);
251 fors_image_list_insert(ilist, ima);
270 const fors_image_list *
273 return (
const fors_image_list *)
280 cpl_image_delete(temp); \
301 cpl_image *data = NULL;
302 cpl_image *variance = NULL;
303 cpl_image *temp = NULL;
304 const char *filename;
308 assure( frame != NULL,
return image, NULL );
310 filename = cpl_frame_get_filename(frame);
311 assure( filename != NULL,
return image,
312 "NULL filename received");
314 cpl_msg_info(cpl_func,
"Loading %s: %s",
316 (cpl_frame_get_tag(frame) != NULL) ?
317 cpl_frame_get_tag(frame) :
"NULL",
321 data = cpl_image_load(filename,
322 FORS_IMAGE_TYPE, plane, extension);
324 assure( !cpl_error_get_code(),
return image,
325 "Could not load image from %s extension %d",
326 filename, extension);
330 if (cpl_frame_get_nextensions(frame) == 0) {
333 variance = cpl_image_new(
334 cpl_image_get_size_x(data),
335 cpl_image_get_size_y(data),
344 variance = cpl_image_load(filename,
345 FORS_IMAGE_TYPE, plane, extension);
347 assure( !cpl_error_get_code(),
return image,
348 "Could not load image from %s extension %d",
349 filename, extension);
351 cpl_image_power(variance, 2);
353 assure( cpl_image_get_min(variance) >= 0,
return image,
354 "Illegal minimum variance: %g",
355 cpl_image_get_min(variance));
357 cpl_image_delete(temp); temp = NULL;
370 cpl_image_delete(sigma); \
371 cpl_propertylist_delete(extension_header); \
384 const char *filename)
386 cpl_propertylist *extension_header = NULL;
387 cpl_image *sigma = NULL;
389 assure( image != NULL,
return, NULL );
391 assure( filename != NULL,
return, NULL );
393 cpl_image_save(image->data, filename, CPL_BPP_IEEE_FLOAT, header,
395 assure( !cpl_error_get_code(),
return,
396 "Cannot save product %s", filename);
398 sigma = cpl_image_power_create(image->variance, 0.5);
400 extension_header = cpl_propertylist_new();
401 cpl_propertylist_append_string(extension_header,
402 "EXTNAME",
"IMAGE.ERR");
404 cpl_image_save(sigma, filename, CPL_BPP_IEEE_FLOAT, extension_header,
406 assure( !cpl_error_get_code(),
return,
407 "Cannot save product %s", filename);
417 cpl_image_delete(var_bkg); \
418 cpl_image_delete(sigma_bkg); \
433 const char *filename_dat,
434 const char *filename_var,
437 cpl_propertylist *extension_header = NULL;
438 cpl_image *sigma_bkg = NULL;
439 cpl_image *var_bkg = NULL;
441 assure( image != NULL,
return, NULL );
443 assure( filename_dat != NULL,
return, NULL );
444 assure( filename_var != NULL,
return, NULL );
446 cpl_image_save(image->data, filename_dat, CPL_BPP_IEEE_FLOAT, header,
448 assure( !cpl_error_get_code(),
return,
449 "Cannot save product %s", filename_dat);
459 cpl_msg_info(cpl_func,
"Creating background error map");
461 bool filter_data =
false;
462 int xstep = radius/2;
469 int ystep = radius/2;
483 assure( !cpl_error_get_code(),
return,
484 "Median filtering failed");
486 sigma_bkg = cpl_image_power_create(var_bkg, 0.5);
488 cpl_image_save(sigma_bkg, filename_var,
489 CPL_BPP_IEEE_FLOAT, extension_header,
491 assure( !cpl_error_get_code(),
return,
492 "Cannot save product %s", filename_var);
507 assure( image != NULL,
return -1, NULL );
508 return cpl_image_get_size_x(image->data);
520 assure( image != NULL,
return -1, NULL );
521 return cpl_image_get_size_y(image->data);
532 assure( image != NULL,
return NULL, NULL );
534 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return NULL, NULL );
538 return cpl_image_get_data_float(image->data);
553 assure( image != NULL,
return, NULL );
555 cpl_image_abs(image->data);
572 assure( image != NULL,
return, NULL );
574 cpl_image_multiply(image->data, image->data);
579 cpl_image_multiply_scalar(image->variance, 2);
588 cpl_image_delete(temp); \
601 cpl_image *temp = NULL;
602 assure( left != NULL,
return, NULL );
603 assure( right != NULL,
return, NULL );
605 cpl_image_subtract(left->data, right->data);
608 cpl_image_add(left->variance, right->variance);
629 assure( left != NULL,
return, NULL );
630 assure( right != NULL,
return, NULL );
631 assure( cpl_image_get_size_x(left->data) == cpl_image_get_size_x(right) &&
632 cpl_image_get_size_y(left->data) == cpl_image_get_size_y(right),
634 "Incompatible data and weight image sizes: "
635 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
636 " and %"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT,
637 cpl_image_get_size_x(left->data),
638 cpl_image_get_size_y(left->data),
639 cpl_image_get_size_x(right),
640 cpl_image_get_size_y(right));
642 cpl_image_multiply(left->data, right);
643 cpl_image_multiply(left->variance, right);
644 cpl_image_multiply(left->variance, right);
670 assure( left != NULL,
return, NULL );
671 assure( right != NULL,
return, NULL );
672 assure( cpl_image_get_size_x(left->data) == cpl_image_get_size_x(right) &&
673 cpl_image_get_size_y(left->data) == cpl_image_get_size_y(right),
675 "Incompatible data and weight image sizes: "
676 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
677 " and %"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT,
678 cpl_image_get_size_x(left->data),
679 cpl_image_get_size_y(left->data),
680 cpl_image_get_size_x(right),
681 cpl_image_get_size_y(right));
684 int nx = cpl_image_get_size_x(right);
685 int ny = cpl_image_get_size_y(right);
686 float *datal = cpl_image_get_data_float(left->data);
687 float *datav = cpl_image_get_data_float(left->variance);
688 float *datar = cpl_image_get_data_float(right);
689 for (y = 0; y < ny; y++) {
690 for (x = 0; x < nx; x++) {
691 if (datar[x + nx*y] == 0) {
695 datav[x + nx*y] = FORS_IMAGE_TYPE_MAX;
700 cpl_image_divide(left->data, right);
701 cpl_image_divide(left->variance, right);
702 cpl_image_divide(left->variance, right);
710 fors_image_delete(&dupl); \
737 assure( left != NULL,
return, NULL );
738 assure( right != NULL,
return, NULL );
742 cpl_image_divide(left->data, dupl->data);
745 cpl_image_multiply(dupl->variance, left->data);
746 cpl_image_multiply(dupl->variance, left->data);
750 cpl_image_add(left->variance, dupl->variance);
754 cpl_image_divide(left->variance, dupl->data);
755 cpl_image_divide(left->variance, dupl->data);
760 int nx = cpl_image_get_size_x(left->data);
761 int ny = cpl_image_get_size_y(left->data);
762 float *datal = cpl_image_get_data_float(left->data);
763 float *datav = cpl_image_get_data_float(left->variance);
764 float *datar = cpl_image_get_data_float(right->data);
765 for (y = 0; y < ny; y++) {
766 for (x = 0; x < nx; x++) {
767 if (datar[x + nx*y] == 0) {
769 datav[x + nx*y] = FORS_IMAGE_TYPE_MAX;
781 cpl_image_delete(s22d12); \
797 cpl_image *s22d12 = NULL;
799 assure( left != NULL,
return, NULL );
800 assure( right != NULL,
return, NULL );
802 s22d12 = cpl_image_duplicate(right->variance);
803 cpl_image_multiply(s22d12, left->data);
804 cpl_image_multiply(s22d12, left->data);
806 cpl_image_multiply(left->variance, right->data);
807 cpl_image_multiply(left->variance, right->data);
808 cpl_image_add(left->variance, s22d12);
810 cpl_image_multiply(left->data, right->data);
833 assure( image != NULL,
return, NULL );
834 assure( ds <= 0,
return,
"Unsupported");
836 cpl_image_subtract_scalar(image->data, s);
858 assure( image != NULL,
return, NULL );
859 assure( s != 0,
return,
"Division by zero");
860 assure( ds <= 0,
return,
"Unsupported");
862 cpl_image_divide_scalar(image->data, s);
863 cpl_image_divide_scalar(image->variance, s*s);
884 assure( image != NULL,
return, NULL );
885 assure( ds <= 0,
return,
"Unsupported");
887 cpl_image_multiply_scalar(image->data, s);
888 cpl_image_multiply_scalar(image->variance, s*s);
896 cpl_image_delete(temp); \
913 cpl_image *temp = NULL;
915 assure( image != NULL,
return, NULL );
916 assure( b >= 0,
return,
"Negative base: %f", b);
917 assure( db <= 0,
return,
"Unsupported");
919 cpl_image_exponential(image->data, b);
923 cpl_image_multiply_scalar(image->variance, lnb*lnb);
924 cpl_image_multiply(image->variance, image->data);
925 cpl_image_multiply(image->variance, image->data);
941 assure( image != NULL,
return 0, NULL );
943 return cpl_image_get_min(image->data);
956 assure( image != NULL,
return 0, NULL );
958 return cpl_image_get_max(image->data);
972 assure( image != NULL,
return 0, NULL );
973 assure( dmean == NULL,
return 0,
"Unsupported");
975 return cpl_image_get_mean(image->data);
989 assure( image != NULL,
return 0, NULL );
990 assure( dmedian == NULL,
return 0,
"Unsupported");
992 return cpl_image_get_median(image->data);
1018 assure( image != NULL,
return, NULL );
1021 return,
"Cannot extraction region (%d, %d) - (%d, %d) of "
1022 "%"CPL_SIZE_FORMAT
"x%"CPL_SIZE_FORMAT
" image",
1027 cpl_image *new_data = cpl_image_extract(image->data,
1030 cpl_image_delete(image->data);
1032 cpl_image* new_variance = cpl_image_extract(image->variance,
1035 cpl_image_delete(image->variance);
1037 image->data = new_data;
1038 image->variance = new_variance;
1080 const cpl_image *input = NULL;
1081 cpl_image *smooth = NULL;
1084 assure( image != NULL,
return smooth, NULL );
1085 passure( image->data != NULL,
return smooth );
1086 passure( image->variance != NULL,
return smooth );
1088 input = (use_data) ? image->data : image->variance;
1090 nx = cpl_image_get_size_x(input);
1091 ny = cpl_image_get_size_y(input);
1093 if (xstep < 1) xstep = 1;
1094 if (ystep < 1) ystep = 1;
1096 assure( 1 <= xstart && xstart <= xend && xend <= nx &&
1097 1 <= ystart && ystart <= yend && yend <= ny,
return smooth,
1098 "Illegal region (%d, %d) - (%d, %d) of %dx%d image",
1103 smooth = cpl_image_duplicate(input);
1106 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return smooth, NULL );
1108 const float *input_data = cpl_image_get_data_float_const(input);
1109 float *smooth_data = cpl_image_get_data_float(smooth);
1110 float *data = cpl_malloc((2*yradius + 1)*(2*xradius + 1)*
sizeof(*data));
1113 for (y = ystart; y < yend; y++) {
1120 int ylo = y - (yradius/ystep) * ystep;
1121 int yhi = y + (yradius/ystep) * ystep;
1123 while (ylo < ystart) ylo += ystep;
1124 while (yhi > yend ) yhi -= ystep;
1127 for (x = xstart; x < xend; x++) {
1128 int xlo = x - (xradius/xstep) * xstep;
1129 int xhi = x + (xradius/xstep) * xstep;
1131 while (xlo < xstart) xlo += xstep;
1132 while (xhi > xend ) xhi -= xstep;
1137 for (j = ylo; j <= yhi; j += ystep) {
1138 for (i = xlo; i <= xhi; i += xstep) {
1139 data[k++] = input_data[ (i-1) + (j-1)*nx ];
1144 smooth_data[ (x-1) + (y-1)*nx ] =
1156 cpl_image_delete(input); \
1159 fors_image_flat_fit_create(
fors_image *image,
1164 cpl_image *temp = NULL;
1165 cpl_image *input = NULL;
1166 cpl_image *smooth = NULL;
1169 assure( image != NULL,
return smooth, NULL );
1170 passure( image->data != NULL,
return smooth );
1171 assure( step > 0,
return smooth, NULL );
1172 assure( degree >= 0,
return smooth, NULL );
1177 nx = cpl_image_get_size_x(temp);
1178 ny = cpl_image_get_size_y(temp);
1184 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return smooth, NULL );
1192 const float *input_data = cpl_image_get_data_float_const(input);
1200 for (y = 0; y < ny; y += step) {
1202 for (x = 0; x < nx; x += step, pos += step) {
1203 if (input_data[pos] > level) {
1209 if (count < (degree+1)*(degree+2)) {
1210 step = sqrt((nx*nx)/((degree+1)*(degree+2))) / 2;
1213 cpl_msg_error(cpl_func,
"Flat field image too small (%dx%d). "
1214 "Please provide a smaller resampling step (a good "
1215 "value would be %d)", nx, ny, step);
1216 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
1226 cpl_bivector *positions = cpl_bivector_new(count);
1227 double *xpos = cpl_bivector_get_x_data(positions);
1228 double *ypos = cpl_bivector_get_y_data(positions);
1229 cpl_vector *fluxes = cpl_vector_new(count);
1230 double *flux = cpl_vector_get_data(fluxes);
1233 for (y = 0; y < ny; y += step) {
1235 for (x = 0; x < nx; x += step, pos += step) {
1236 if (input_data[pos] > level) {
1239 flux[count] = input_data[pos];
1245 cpl_image_delete(input); input = NULL;
1252 cpl_polynomial *model = cpl_polynomial_fit_2d_create(positions,
1257 cpl_bivector_delete(positions);
1258 cpl_vector_delete(fluxes);
1260 smooth = cpl_image_new(nx, ny, FORS_IMAGE_TYPE);
1261 float *smooth_data = cpl_image_get_data_float(smooth);
1263 cpl_vector *point = cpl_vector_new(2);
1264 double *dpoint = cpl_vector_get_data(point);
1266 for (y = 0; y < ny; y++) {
1269 for (x = 0; x < nx; x++, pos++) {
1271 smooth_data[pos] = cpl_polynomial_eval(model, point);
1275 cpl_polynomial_delete(model);
1276 cpl_vector_delete(point);
1307 const cpl_image *input = NULL;
1308 cpl_image *hmaxima = NULL;
1309 cpl_image *maxima = NULL;
1312 assure( image != NULL,
return maxima, NULL );
1313 passure( image->data != NULL,
return maxima );
1314 passure( image->variance != NULL,
return maxima );
1316 input = (use_data) ? image->data : image->variance;
1318 nx = cpl_image_get_size_x(input);
1319 ny = cpl_image_get_size_y(input);
1325 hmaxima = cpl_image_duplicate(input);
1328 assure( FORS_IMAGE_TYPE == CPL_TYPE_FLOAT,
return maxima, NULL );
1330 float *input_data = (
float *)cpl_image_get_data_float_const(input);
1331 float *maxima_data = cpl_image_get_data_float(hmaxima);
1334 for (y = 0; y < ny; y++) {
1335 const float *irow = input_data + y * nx;
1336 float *orow = maxima_data + y * nx;
1337 max_filter(irow, orow, nx, 2*xradius+1);
1340 cpl_image_turn(hmaxima, 1);
1346 maxima = cpl_image_duplicate(hmaxima);
1347 input_data = cpl_image_get_data_float(hmaxima);
1348 maxima_data = cpl_image_get_data_float(maxima);
1355 for (x = 0; x < nx; x++) {
1356 const float *irow = input_data + x * ny;
1357 float *orow = maxima_data + x * ny;
1358 max_filter(irow, orow, ny, 2*yradius+1);
1361 cpl_image_delete(hmaxima);
1363 cpl_image_turn(maxima, -1);
1379 assure( image != NULL,
return 0, NULL );
1380 assure( dstdev == NULL,
return 0,
"Unsupported");
1382 return cpl_image_get_stdev(image->data);
1387 cpl_mask_delete(rejected); \
1388 cpl_image_delete(im); \
1402 cpl_mask *rejected = NULL;
1403 cpl_image *im = NULL;
1405 assure( image != NULL,
return 0, NULL );
1406 assure( cut > 0,
return 0,
"Illegal cut: %f", cut );
1407 assure( dstdev == NULL,
return 0,
"Unsupported");
1411 im = cpl_image_duplicate(image->data);
1412 cpl_image_subtract_scalar(im, median);
1413 cpl_image_power(im, 2);
1416 rejected = cpl_mask_threshold_image_create(image->data,
1419 cpl_mask_not(rejected);
1420 cpl_image_reject_from_mask(im, rejected);
1422 double robust_stdev = sqrt(cpl_image_get_mean(im));
1425 return robust_stdev;
1445 assure( image != NULL,
return 0, NULL );
1446 assure( dmean == NULL,
return 0,
"Unsupported");
1448 avg = cpl_image_get_mean(image->variance);
1451 assure( avg >= 0,
return -1,
"Average variance is %f", avg);
1460 cpl_imagelist_delete(datlist); \
1461 cpl_imagelist_delete(varlist); \
1475 cpl_imagelist *datlist = NULL;
1476 cpl_imagelist *varlist = NULL;
1477 cpl_image *data = NULL;
1478 cpl_image *variance = NULL;
1482 assure( images != NULL,
return NULL, NULL );
1483 assure( fors_image_list_size(images) > 0,
return NULL,
1484 "Cannot stack zero images");
1486 i = fors_image_list_first_const(images);
1488 datlist = cpl_imagelist_new();
1489 varlist = cpl_imagelist_new();
1494 cpl_imagelist_set(datlist,
1495 cpl_image_duplicate(i->data),
1496 cpl_imagelist_get_size(datlist));
1497 cpl_imagelist_set(varlist,
1498 cpl_image_duplicate(i->variance),
1499 cpl_imagelist_get_size(varlist));
1500 i = fors_image_list_next_const(images);
1504 #ifdef CPL_IS_NOT_CRAP
1505 data = cpl_imagelist_collapse_create(datlist);
1507 variance = cpl_imagelist_collapse_create(varlist);
1514 cpl_image_divide_scalar(variance, N);
1524 cpl_imagelist_delete(datlist); \
1525 cpl_imagelist_delete(varlist); \
1542 cpl_imagelist *datlist = NULL;
1543 cpl_imagelist *varlist = NULL;
1544 cpl_image *data = NULL;
1545 cpl_image *variance = NULL;
1549 assure( images != NULL,
return NULL, NULL );
1550 assure( fors_image_list_size(images) > low + high,
return NULL,
1551 "Cannot reject more images than there are");
1552 assure( low*high >= 0 && low+high > 0,
return NULL,
1553 "Invalid minmax rejection criteria");
1555 i = fors_image_list_first_const(images);
1557 datlist = cpl_imagelist_new();
1558 varlist = cpl_imagelist_new();
1563 cpl_imagelist_set(datlist,
1564 cpl_image_duplicate(i->data),
1565 cpl_imagelist_get_size(datlist));
1566 cpl_imagelist_set(varlist,
1567 cpl_image_duplicate(i->variance),
1568 cpl_imagelist_get_size(varlist));
1569 i = fors_image_list_next_const(images);
1573 data = cpl_imagelist_collapse_minmax_create(datlist, low, high);
1574 variance = cpl_imagelist_collapse_minmax_create(varlist, low, high);
1576 cpl_image_divide_scalar(variance, N);
1596 int low,
int high,
int iter)
1598 cpl_imagelist *datlist = NULL;
1599 cpl_imagelist *varlist = NULL;
1600 cpl_image *data = NULL;
1601 cpl_image *variance = NULL;
1602 cpl_image *ngood = NULL;
1605 assure( images != NULL,
return NULL, NULL );
1607 i = fors_image_list_first_const(images);
1609 datlist = cpl_imagelist_new();
1610 varlist = cpl_imagelist_new();
1615 cpl_imagelist_set(datlist,
1616 cpl_image_duplicate(i->data),
1617 cpl_imagelist_get_size(datlist));
1618 cpl_imagelist_set(varlist,
1619 cpl_image_duplicate(i->variance),
1620 cpl_imagelist_get_size(varlist));
1621 i = fors_image_list_next_const(images);
1625 variance = cpl_imagelist_collapse_create(varlist);
1627 cpl_image_divide(variance, ngood);
1629 cpl_image_delete(ngood);
1649 cpl_imagelist *datlist = NULL;
1650 cpl_imagelist *varlist = NULL;
1651 cpl_image *data = NULL;
1652 cpl_image *variance = NULL;
1656 assure( images != NULL,
return NULL, NULL );
1657 assure( fors_image_list_size(images) > 0,
return NULL,
1658 "Cannot stack zero images");
1660 i = fors_image_list_first_const(images);
1662 datlist = cpl_imagelist_new();
1663 varlist = cpl_imagelist_new();
1666 cpl_imagelist_set(datlist,
1667 cpl_image_duplicate(i->data),
1668 cpl_imagelist_get_size(datlist));
1669 cpl_imagelist_set(varlist,
1670 cpl_image_duplicate(i->variance),
1671 cpl_imagelist_get_size(varlist));
1673 i = fors_image_list_next_const(images);
1677 #ifdef CPL_IS_NOT_CRAP
1678 data = cpl_imagelist_collapse_median_create(datlist);
1680 variance = cpl_imagelist_collapse_create(varlist);
1687 cpl_image_divide_scalar(variance, N);
1689 cpl_image_multiply_scalar(variance,
1718 int radius,
double color)
1720 assure( image != NULL,
return, NULL );
1722 assure( type == 0 || type == 1 || type == 2,
1723 return ,
"Unsupported type %d", type);
1725 assure( radius > 0,
return, NULL );
1729 for (i = 0; i < 360; i++) {
1732 int px = x + radius*cos(i/(2*M_PI));
1733 int py = y + radius*sin(i/(2*M_PI));
1735 if (1 <= px && px <= cpl_image_get_size_x(image->data) &&
1736 1 <= py && py <= cpl_image_get_size_y(image->data)) {
1737 cpl_image_set(image->data, px, py, color);
1738 cpl_image_set(image->variance, px, py, color > 0 ? color : 0);
1745 for (i = -radius; i <= radius; i++) {
1758 if (1 <= px && px <= cpl_image_get_size_x(image->data) &&
1759 1 <= py && py <= cpl_image_get_size_y(image->data)) {
1760 cpl_image_set(image->data , px, py, color);
1761 cpl_image_set(image->variance, px, py, color > 0 ? color : 0);
1769 hdrl_imagelist * fors_image_list_to_hdrl(
const fors_image_list * imalist)
1772 hdrl_imagelist * images_hdrl = hdrl_imagelist_new();
1773 const fors_image * target = fors_image_list_first_const(imalist);
1774 for(i = 0 ; i < fors_image_list_size(imalist); ++i)
1776 const cpl_image * ima_data = target->data;
1777 cpl_image * ima_error = cpl_image_power_create(target->variance, 0.5);
1778 hdrl_image * ima_hdrl = hdrl_image_create(ima_data, ima_error);
1779 hdrl_imagelist_set(images_hdrl, ima_hdrl,
1780 hdrl_imagelist_get_size(images_hdrl));
1781 target = fors_image_list_next_const(imalist);
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_image_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.
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.