From 115aa0b77f4419455a4c41a7ca1d3bc558a60ddf Mon Sep 17 00:00:00 2001 From: Dugal Harris Date: Sun, 17 Mar 2024 13:15:13 +0200 Subject: [PATCH] minor updates --- orthority/ortho.py | 6 +++--- orthority/utils.py | 33 +++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/orthority/ortho.py b/orthority/ortho.py index dd4a00d..2eadf44 100644 --- a/orthority/ortho.py +++ b/orthority/ortho.py @@ -255,7 +255,7 @@ def area_poly(coords: np.ndarray) -> float: # find image boundary in pixel coordinates, and world coordinates at z=median(DEM) (note: # ignores vertical datum shifts) ji = self._camera.pixel_boundary() - xy = self._camera.pixel_to_world_z(ji, np.nanmedian(self._dem_array))[:2] + xy = self._camera.world_boundary(np.nanmedian(self._dem_array))[:2] # return the average pixel resolution inside the world boundary pixel_area = area_poly(ji.T) @@ -642,10 +642,10 @@ def process( src_im = exit_stack.enter_context(utils.OpenRaster(self._src_file, 'r')) # warn if source dimensions don't match camera - if src_im.shape[::-1] != self._camera._im_size: + if src_im.shape[::-1] != self._camera.im_size: warnings.warn( f"Source image '{self._src_name}' size: {src_im.shape[::-1]} does not " - f"match camera image size: {self._camera._im_size}." + f"match camera image size: {self._camera.im_size}." ) # get dem array covering ortho extents in world / ortho crs and ortho resolution diff --git a/orthority/utils.py b/orthority/utils.py index 065ba36..af52b58 100644 --- a/orthority/utils.py +++ b/orthority/utils.py @@ -73,14 +73,14 @@ def nan_equals(a: np.ndarray | float, b: np.ndarray | float) -> np.ndarray: def distort_image(camera, image: np.ndarray, nodata=0, interp=Interp.nearest) -> np.ndarray: - """Return a distorted image given a camera model and source image.""" + """Return a distorted image given a frame camera model and source image.""" - if not np.all(np.array(image.shape[::-1]) == camera._im_size): + if not np.all(np.array(image.shape[-2:][::-1]) == camera.im_size): raise ValueError("'image' shape should be the same as the 'camera' image size.") # create (j, i) pixel coords for distorted image - j_range = np.arange(0, camera._im_size[0]) - i_range = np.arange(0, camera._im_size[1]) + j_range = np.arange(0, camera.im_size[0]) + i_range = np.arange(0, camera.im_size[1]) j_grid, i_grid = np.meshgrid(j_range, i_range, indexing='xy') ji = np.row_stack((j_grid.reshape(1, -1), i_grid.reshape(1, -1))) @@ -88,16 +88,21 @@ def distort_image(camera, image: np.ndarray, nodata=0, interp=Interp.nearest) -> camera_xyz = camera._pixel_to_camera(ji) undist_ji = camera._K_undistort.dot(camera_xyz)[:2].astype('float32') - # remap the distorted image from the source image - dist_image = np.full_like(image, fill_value=nodata) - cv2.remap( - image, - undist_ji[0].reshape(image.shape), - undist_ji[1].reshape(image.shape), - interp.to_cv(), - dst=dist_image, - borderMode=cv2.BORDER_TRANSPARENT, - ) + def distort_band(src_array: np.ndarray, dst_array: np.ndarray): + """Distort a 2D band array.""" + cv2.remap( + src_array, + undist_ji[0].reshape(image.shape[-2:]), + undist_ji[1].reshape(image.shape[-2:]), + Interp[interp].to_cv(), + dst=dst_array, + borderMode=cv2.BORDER_TRANSPARENT, + ) + + dist_image = np.full(image.shape, dtype=image.dtype, fill_value=nodata) + for bi in range(image.shape[0]): + distort_band(image[bi], dist_image[bi]) + return dist_image