Fix a number of multi-resolution resampling bugs

This commit is contained in:
Gareth Evans
2017-06-26 22:55:04 +01:00
parent 8f13dae8b4
commit 820c3fa31d
3 changed files with 19 additions and 13 deletions

View File

@@ -219,7 +219,7 @@ int loadLIDAR(char *filenames, int resample)
/* Iterate through all of the tiles to find the smallest resolution. We will /* Iterate through all of the tiles to find the smallest resolution. We will
* need to rescale every tile from here on out to this value */ * need to rescale every tile from here on out to this value */
int smallest_res = 0; float smallest_res = 0;
for (size_t i = 0; i < fc; i++) { for (size_t i = 0; i < fc; i++) {
if ( smallest_res == 0 || tiles[i].resolution < smallest_res ){ if ( smallest_res == 0 || tiles[i].resolution < smallest_res ){
smallest_res = tiles[i].resolution; smallest_res = tiles[i].resolution;
@@ -228,8 +228,8 @@ int loadLIDAR(char *filenames, int resample)
/* Now we need to rescale all tiles the the lowest resolution or the requested resolution. ie if we have /* Now we need to rescale all tiles the the lowest resolution or the requested resolution. ie if we have
* one 1m lidar and one 2m lidar, resize the 2m to fake 1m */ * one 1m lidar and one 2m lidar, resize the 2m to fake 1m */
int desired_resolution = resample != 0 && smallest_res < resample ? resample : smallest_res; float desired_resolution = resample != 0 && smallest_res < resample ? resample : smallest_res;
if (desired_resolution > resample && debug ) if (desired_resolution > resample && resample != 0 && debug )
fprintf(stderr, "Warning: Unable to rescale to requested resolution\n"); fprintf(stderr, "Warning: Unable to rescale to requested resolution\n");
for (size_t i = 0; i< fc; i++) { for (size_t i = 0; i< fc; i++) {
float rescale = tiles[i].resolution / (float)desired_resolution; float rescale = tiles[i].resolution / (float)desired_resolution;
@@ -246,7 +246,7 @@ int loadLIDAR(char *filenames, int resample)
double total_width = max_west - min_west >= 0 ? max_west - min_west : max_west + (360 - min_west); double total_width = max_west - min_west >= 0 ? max_west - min_west : max_west + (360 - min_west);
double total_height = max_north - min_north; double total_height = max_north - min_north;
if (debug) { if (debug) {
fprintf(stderr, "totalwidth: %.7f - %.7f = %.7f\n", max_west, min_west, total_width); fprintf(stderr,"totalw: %.7f - %.7f = %.7f\n", max_west, min_west, total_width);
fprintf(stderr,"mw:%lf Mnw:%lf\n", max_west, min_west); fprintf(stderr,"mw:%lf Mnw:%lf\n", max_west, min_west);
} }
/* This is how we should _theoretically_ work this out, but due to /* This is how we should _theoretically_ work this out, but due to

View File

@@ -117,7 +117,10 @@ int tile_load_lidar(tile_t *tile, char *filename){
} }
double current_res_km = haversine_formula(tile->max_north, tile->max_west, tile->max_north, tile->min_west); double current_res_km = haversine_formula(tile->max_north, tile->max_west, tile->max_north, tile->min_west);
tile->resolution = (int) ceil((current_res_km/MAX(tile->width,tile->height))*1000); tile->precise_resolution = (current_res_km/MAX(tile->width,tile->height)*1000);
// Round to nearest 0.5
tile->resolution = tile->precise_resolution < 0.5f ? 0.5f : floor((tile->precise_resolution * 2)+0.5) / 2;
tile->width_deg = tile->max_west - tile->min_west >= 0 ? tile->max_west - tile->min_west : tile->max_west + (360 - tile->min_west); tile->width_deg = tile->max_west - tile->min_west >= 0 ? tile->max_west - tile->min_west : tile->max_west + (360 - tile->min_west);
tile->height_deg = tile->max_north - tile->min_north; tile->height_deg = tile->max_north - tile->min_north;
@@ -126,7 +129,7 @@ int tile_load_lidar(tile_t *tile, char *filename){
tile->ppdy = tile->height / tile->height_deg; tile->ppdy = tile->height / tile->height_deg;
if (debug) if (debug)
fprintf(stderr,"Pixels loaded: %zu/%d (PPD %dx%d)\n", loaded, tile->width*tile->height, tile->ppdx, tile->ppdy); fprintf(stderr,"Pixels loaded: %zu/%d (PPD %dx%d, Res %f (%.2f))\n", loaded, tile->width*tile->height, tile->ppdx, tile->ppdy, tile->precise_resolution, tile->resolution);
/* All done, close the LIDAR file */ /* All done, close the LIDAR file */
fclose(fd); fclose(fd);
@@ -171,7 +174,7 @@ int tile_rescale(tile_t *tile, float scale){
} }
if (debug) if (debug)
fprintf(stderr,"Resampling tile:\n\tOld %zux%zu. New %zux%zu\n\tScale %f Skip %zu Copy %zu\n", tile->width, tile->height, new_width, new_height, scale, skip_count, copy_count); fprintf(stderr,"Resampling tile %s [%.1f]:\n\tOld %zux%zu. New %zux%zu\n\tScale %f Skip %zu Copy %zu\n", tile->resolution, tile->filename, tile->width, tile->height, new_width, new_height, scale, skip_count, copy_count);
/* Nearest neighbour normalization. For each subsample of the original, simply /* Nearest neighbour normalization. For each subsample of the original, simply
* assign the value in the top left to the new pixel * assign the value in the top left to the new pixel
@@ -210,11 +213,13 @@ int tile_rescale(tile_t *tile, float scale){
/* Update the height and width values */ /* Update the height and width values */
tile->height = new_height; tile->height = new_height;
tile->width = new_width; tile->width = new_width;
tile->resolution *= scale; tile->resolution *= 1/scale; // A scale of 2 is HALF the resolution
tile->ppdy *= scale; tile->ppdx = tile->width / tile->width_deg;
tile->ppdx *= scale; tile->ppdy = tile->height / tile->height_deg;
tile->width_deg *= scale; // tile->width_deg *= scale;
tile->height_deg *= scale; // tile->height_deg *= scale;
if (debug)
fprintf(stderr, "Resampling complete. New resolution: %.1f\n", tile->resolution);
return 0; return 0;
} }

View File

@@ -33,7 +33,8 @@ typedef struct _tile_t{
short max_el; short max_el;
short min_el; short min_el;
short *data; short *data;
int resolution; float precise_resolution;
float resolution;
double width_deg; double width_deg;
double height_deg; double height_deg;
int ppdx; int ppdx;