/* See {rdo_image.h} */ #define rdo_image_C_COPYRIGHT "Copyright © 2008 Danillo Pereira and J. Stolfi, UNICAMP" /* Last edited on 2024-12-21 11:52:37 by stolfi */ #include #include #include #include #include #include #include #include void rdo_image_find_max_min(image_t *img, float *vMin, float *vMax) { int nc = (int)img->sz[0]; *vMin = +INF; *vMax = -INF; int channel; for (channel = 0; channel < nc; channel++) { float_image_update_sample_range(img, channel, vMin, vMax); } } void rdo_image_map_zero_to_half(image_t *img) { int nc = (int)img->sz[0]; /* Find the maximum and minimum sample value, ignoring {±INF}s and {NAN}s: */ float vMin, vMax; rdo_image_find_max_min(img, &vMin, &vMax); bool_t fudged = FALSE; /* Tells whether {vMax} was artifically increased. */ /* Make sure that {vMax} is positive: */ if (vMax <= 0.0) { vMax = (float)1.0e-38; fudged = TRUE; } /* If {vMin} is negative, make sure that {vMax} is not less than {-vMin}: */ if ((vMin < 0.0) && (vMax < -vMin)) { vMax = -vMin; fudged = TRUE; } int channel; for (channel = 0; channel < nc; channel++) { /* Map all normal sample values from {[-vMax _ vMax]} to {[0 _ 1]}: */ float_image_rescale_samples(img, channel, -vMax, vMax, 0.0, 1.0); if (fudged) { /* Add a single white pixel, to avoid normalization: */ float_image_set_sample(img, channel, 0, 0, 1.000); } } } void rdo_image_map_max_to_one(image_t *img) { int nc = (int)img->sz[0]; /* Find the maximum and minimum sample value, ignoring {±INF}s and {NAN}s: */ float vMin, vMax; rdo_image_find_max_min(img, &vMin, &vMax); /* Make sure that {vMax} is positive: */ if (vMax <= 0.0) { vMax = (float)1.0e-38; } int channel; for (channel = 0; channel < nc; channel++) { /* Map all normal sample values from {[0 _ vMax]} to {[0 _ 1]}: */ float_image_rescale_samples(img, channel, 0.000, vMax, 0.0, 1.0); } } void rdo_image_write(char *outDir, char *name, image_t *img, double gamma) { int nc = (int)img->sz[0]; int nx = (int)img->sz[1]; int ny = (int)img->sz[2]; /* Replace any {NAN}s by a funny color: */ int c, x, y; for (c = 0; c < nc; c++) for (y = 0; y < ny; y++) for (x = 0; x < nx; x++) { float *p = float_image_get_sample_address(img, c, x, y); if (isnan(*p)) { (*p) = (float)(0.100 + c * 0.100); } } /* Write the image as PGM or PPM, with gamma correction: */ char *filename = jsprintf("%s/%s.%s", outDir, name, (nc == 1 ? "pgm" : "ppm")); bool_t isMask = FALSE; /* Assume smooth distr of pixel values: */ float_image_write_pnm_named(filename, img, isMask, gamma, BT_BIAS, TRUE, TRUE, FALSE); free(filename); } void rdo_image_compute_pixel_center_coords(int ih, int iv, double *hP, double *vP) { (*hP) = ih + 0.5; (*vP) = iv + 0.5; } void rdo_image_coords_to_pixel_indices(double h, double v, int *ihP, int *ivP) { (*ihP) = (int)floor(h); (*ivP) = (int)floor(v); } void rdo_image_coords_to_projection_coords(double h, double v, int nh, int nv, double *xP, double *yP) { double pix_size = 2.0/hypot(nh, nv); /* Pixel size in projection plane coords. */ double hc = ((double)nh)/2; /* H coordinate of image center. */ double vc = ((double)nv)/2; /* V coordinate of image center. */ (*xP) = ((double)h - hc)*pix_size; (*yP) = (vc - (double)v)*pix_size; } void rdo_image_coords_from_projection_coords(double x, double y, int nh, int nv, double *hP, double *vP) { double img_radius = hypot(nh, nv)/2; /* Radius of image in pixels. */ double hc = ((double)nh)/2; /* H coordinate of image center. */ double vc = ((double)nv)/2; /* V coordinate of image center. */ (*hP) = hc + x*img_radius; (*vP) = vc - y*img_radius; }