Commit 27499263 authored by Bauck, Kirsten (Contractor) Hailey's avatar Bauck, Kirsten (Contractor) Hailey
Browse files

Merge branch 'main' into 'main'

Adds overlap check to ensure image exists

See merge request astrogeology/autocnet!676
parents 506b3b3f f4dce409
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -34,6 +34,9 @@ release.
-->
-->
## [Unreleased]
## [Unreleased]


### Added
- Logging to `affine` transformation that warns when the absolute value of the shear on the affine transformation is greater than 1e-2. High shear in the transformation matric was observed attempting to match nadir LROC-NAC to high slew LROC-NAC data. These high slew images do not match well to nadir images. Additionally, the `x_read_length` and `y_read_length` variables in the `Roi` class (`roi.py`) have a hard coded read length of two times the passed size. This read size is insufficient as the affine shear increases. A candidate enhancement would be to automatically compute the read size based on the affine transformation. This was not done in this addition as matching between high slew and nadir images using a correlation coefficient based approach is quite poor.
- Image check into `place_points_in_overlap` that ensures that the candidate reference image exists on disk. If it does not, the algorithm skips attempting to place points in that image and attempts to use the next image. This was added for LROC NAC control as some images may fail to download.
### Fixed
### Fixed
- `place_points_in_overlap` bug where if any of the points in the overlap failed to project into an image, all points in the overlap were lost. This was caused by #580, which allowed for multiple (a list) of inputs. The error handling was removed from the `image_to_ground` call so the `except` in `place_points_in_overlap` was never called.
- `place_points_in_overlap` bug where if any of the points in the overlap failed to project into an image, all points in the overlap were lost. This was caused by #580, which allowed for multiple (a list) of inputs. The error handling was removed from the `image_to_ground` call so the `except` in `place_points_in_overlap` was never called.
## [1.0.0-rc2]
## [1.0.0-rc2]
+4 −0
Original line number Original line Diff line number Diff line
import os
import time
import time
import logging
import logging
import json
import json
@@ -295,6 +296,9 @@ def place_points_in_overlap(overlap,
                # If this try/except fails, then the reference_index could be wrong because the length
                # If this try/except fails, then the reference_index could be wrong because the length
                # of the measures list is different than the length of the nodes list that was used
                # of the measures list is different than the length of the nodes list that was used
                # to find the most interesting feature.
                # to find the most interesting feature.
                if not os.path.exists(node["image_path"]):
                    log.warning(f'Unable to find input image {node["image_path"]}')
                    continue
                sample, line = isis.ground_to_image(node["image_path"], updated_lon, updated_lat)
                sample, line = isis.ground_to_image(node["image_path"], updated_lon, updated_lat)
                if sample == None or line == None:
                if sample == None or line == None:
                #except CalledProcessError as e:
                #except CalledProcessError as e:
+12 −2
Original line number Original line Diff line number Diff line
@@ -69,7 +69,8 @@ def estimate_affine_from_sensors(reference_image,
    # Dispatch to the sensor to get the a priori pixel location in the input image
    # Dispatch to the sensor to get the a priori pixel location in the input image
    lons, lats = isis.image_to_ground(reference_image.file_name, x_coords, y_coords, allowoutside=True)
    lons, lats = isis.image_to_ground(reference_image.file_name, x_coords, y_coords, allowoutside=True)
    xs, ys = isis.ground_to_image(moving_image.file_name, lons, lats, allowoutside=True)
    xs, ys = isis.ground_to_image(moving_image.file_name, lons, lats, allowoutside=True)

    log.debug(f'Lon/Lats for affine estimate are: {list(zip(lons, lats))}')
    log.debug(f'Image X / Image Y for affine estimate are: {list(zip(xs, ys))}')


    # Check for any coords that do not project between images
    # Check for any coords that do not project between images
    base_gcps = []
    base_gcps = []
@@ -82,7 +83,10 @@ def estimate_affine_from_sensors(reference_image,
    if len(dst_gcps) < 3:
    if len(dst_gcps) < 3:
        raise ValueError(f'Unable to find enough points to compute an affine transformation. Found {len(dst_corners)} points, but need at least 3.')
        raise ValueError(f'Unable to find enough points to compute an affine transformation. Found {len(dst_corners)} points, but need at least 3.')


    log.debug(f'Number of GCPs for affine estimation: {len(dst_gcps)}')

    affine = tf.estimate_transform('affine', np.array([*base_gcps]), np.array([*dst_gcps]))
    affine = tf.estimate_transform('affine', np.array([*base_gcps]), np.array([*dst_gcps]))
    log.debug(f'Computed afffine: {affine}')
    t2 = time.time()
    t2 = time.time()
    log.debug(f'Estimation of local affine took {t2-t1} seconds.')
    log.debug(f'Estimation of local affine took {t2-t1} seconds.')
    return affine
    return affine
@@ -119,7 +123,13 @@ def estimate_local_affine(reference_roi, moving_roi):
                                                    size_x=size_x, 
                                                    size_x=size_x, 
                                                    size_y=size_y)
                                                    size_y=size_y)



    log.debug(f'Affine shear: {affine_transform.shear}')
    if abs(affine_transform.shear) > 1e-2:
        # Matching LROC NAC high slew images to nadir images demonstrated that affine transformations
        # with high shear match poorly. The search templates also have reflection (ROI object, x/y_read_length)
        # because a high shear affine requires  alot of data to be read in. 
        # TODO: Consider handling this differently in the future should nadir to high slew image matching be required.
        log.warn(f'Affine shear: {affine_transform.shear} is greater than 1e-2. It is highly unlikely that these images will match.')
    # The above coordinate transformation to get the center of the ROI handles translation. 
    # The above coordinate transformation to get the center of the ROI handles translation. 
    # So, we only need to rotate/shear/scale the ROI. Omitting scale, which should be 1 (?) results
    # So, we only need to rotate/shear/scale the ROI. Omitting scale, which should be 1 (?) results
    # in an affine transoformation that does not match the full image affine
    # in an affine transoformation that does not match the full image affine