#ifndef dsm_image_H #define dsm_image_H #include #include typedef struct dsm_image_t { int nx; /*width*/ int ny; /*height*/ uint8_t *p; /*pixels linearized by row*/ } dsm_image_t; /* Allocates image and sets all pixels to {fill}. */ dsm_image_t dsm_image_alloc (int nx, int ny, uint8_t fill); /* Sets the image dimensions to {nx,ny}. If {img->p} is not {NULL} and large enough, it weill be reused, else it will be (re)allocated. In any case, it will be filled with {fill}. */ void dsm_image_realloc(dsm_image_t *img, int nx, int ny, uint8_t fill); /* Copies image {img} into {copy}, which must be allocated and must have the same size as {img}. */ void dsm_image_copy(dsm_image_t *img, dsm_image_t *copy); /* Copies into {crop} the part of {full} with the same size as {crop}, skipping the first {dx} columns and {dy} rows. */ void dsm_image_crop(dsm_image_t *full, int dx, int dy, dsm_image_t *crop); /* Stores into {diff} the pixel by pixel difference between {img0} and {img1}, multiplied by {scale} The input images are assumed to be encoded {[0 _ 1] --> {0..255}}. The {diff} image will be encoded {[-1 + +1] --> {0..255}. */ void dsm_image_difference(dsm_image_t *img0, dsm_image_t *img1, double scale, dsm_image_t *diff); /* Copies into {band} a full--width band of pixels from {img} centered on row {y0}. The height of {band} must be odd. */ void dsm_image_extract_band(dsm_image_t *img, int y0, dsm_image_t *band); /*Reduces the image {img} by factors {1/xreduc} and {1/yreduc}, using a smoothing window of {ynlines} rows and {xnlines} columns. Returns the result in {red}. */ void dsm_image_shrink ( dsm_image_t *img, int xreduc, int yreduc, int xnlines, int ynlines, dsm_image_t *red ); /*Stores in {blur} an image, where each pixel is the average of the pixels around it in the image {img}. Uses a Hahn window of {2*ry + 1} rows and {2*rx+1} columns. */ void dsm_image_blur (dsm_image_t *img, int rx, int ry, dsm_image_t *blur); /* Stores into {high} a high-pass filtered version of {img}, using the difference between {img} and a blurred version of {img} obtained by {dsm_image_blur} with parameters {rx,ry}. The difference is scaled down by 1/2 and shifted by 127. */ void dsm_image_high_pass(dsm_image_t *img, int rx, int ry, dsm_image_t *high); /* Same as {dsm_image_high_pass}, but does the filtering in log scale, */ void dsm_image_log_high_pass(dsm_image_t *img, int rx, int ry, dsm_image_t *high, dsm_image_t *temp); /*Stores in {imlog} an image, where each pixel is the the corresponding pixel {p} of {img} mapped by the formula {255*(A*log(p/255) + B)}. */ void dsm_image_to_logscale(dsm_image_t *img, double A, double B, dsm_image_t *imlog); /*Stores in {imlin} an image, where each pixel is the the corresponding pixel {p} of {img} mapped by the formula {255*exp(p/255 - B)/A)}. */ void dsm_image_to_linscale(dsm_image_t *img, double A, double B, dsm_image_t *imlin); /*Convert a double in the range {[pmin _ pmax]} to a pixel value (uint8_t) in {0..255}, with rounding and clipping. */ uint8_t dsm_image_quantize (double p, double pmin, double pmax); /*Convert a pixel value (uint8_t) in {0..255} to a double in the range {[pmin _ pmax]}. */ double dsm_image_floatize (uint8_t pint, double pmin, double pmax); /*Allocate and compute the Hahn weight table w[0..n-1].*/ double* dsm_image_compute_hahn_weights (int n); /*Computes the average of image {img} around the pixel row {y} column {x}. Uses a window of {2*ry + 1} rows and {2*rx+1} columns. Expects that {wx} will be a Hahn weight table with {2*rx + 1} elements and similarly for {wy}. */ double dsm_image_compute_local_avg ( dsm_image_t *img, int x, int y, int rx, double wx[], int ry, double wy[] ); /* Applies median filter with window of half-width {radius} to {img}, stores resulr into {res}. */ void dsm_image_median_filter (dsm_image_t *img, dsm_image_t *res, int radius); /* qsort {int} comparison function */ int dsm_image_compare_pixels(const void *p, const void *q); /*Returns the minimum of the pixels in {img}. */ double dsm_image_min (dsm_image_t *img); /*Returns the minimum of the pixels in rows {by..ey} of {img}. */ double dsm_image_min_band (dsm_image_t *img, int by, int ey); /* Read an ASCII or binary PGM file. If {img->p} is not {NULL} and large enough, it weill be reused, else it will be (re)allocated. */ void dsm_image_read_pgm_ascii(FILE *rd, dsm_image_t *img); void dsm_image_read_pgm_raw(FILE *rd, dsm_image_t *img); /* Writes binary PGM or PPM image file. */ void dsm_image_write_pgm_raw(FILE *wr, dsm_image_t *img); void dsm_image_write_ppm_raw(FILE *wr, dsm_image_t *imgR, dsm_image_t *imgG, dsm_image_t *imgB); /* Writes {img} as a PGM file called "{prefix}_{FFFFFF}_{NNNNN}_{tag}.pgm" where {FFFFFF} is the 6-digit value of {frame} and {NNNN} is the 4-digit value of {iter}. The parts "_{FFFFFF}" is omitted if {frame} is negative, and "_{NNNN}" is omitted if {iter} is negative. */ void dsm_image_debug(dsm_image_t *img, const char *prefix, int frame, int iter, const char *tag); /*Morphological erosion of the image {img}. Expands low values by {r} elements in each direction. Uses the image {temp} as work area. */ void dsm_image_erode (dsm_image_t *img, int r, dsm_image_t *temp); /*Morphological dilation of the image {img}. Expands high values by {r} elements in each direction.; Uses the image {temp} as work area.*/ void dsm_image_dilate (dsm_image_t *img, int r, dsm_image_t *temp); #endif