Unverified Commit 187e83bb authored by jlaura's avatar jlaura Committed by GitHub
Browse files

Fixes 606 and an unidentified overlap bug (#612)

parent dd77e5eb
Loading
Loading
Loading
Loading
+30 −17
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ import cv2
from skimage import transform as tf
from skimage import registration 
from skimage import filters
from skimage.util import img_as_float32
from scipy import fftpack

from matplotlib import pyplot as plt
@@ -523,7 +524,7 @@ def subpixel_template_classic(sx, sy, dx, dy,
    if (s_image is None) or (d_template is None):
        return None, None, None, None

    shift_x, shift_y, metrics, corrmap = func(d_template.astype('float32'), s_image.astype('float32'), **kwargs)
    shift_x, shift_y, metrics, corrmap = func(img_as_float32(d_template), img_as_float32(s_image), **kwargs)
    if shift_x is None:
        return None, None, None, None
    # Apply the shift and return
@@ -1521,7 +1522,6 @@ def subpixel_register_point(pointid,
        for measure in measures:
            res = session.query(Images).filter(Images.id == measure.imageid).one()
            nodes[measure.imageid] = NetworkNode(node_id=measure.imageid, image_path=res.path)

        session.expunge_all()

    resultlog = []
@@ -2172,41 +2172,46 @@ def subpixel_register_point_smart(pointid,
    
    t1 = time.time()
    with ncg.session_scope() as session:
        # Order by is important here because the measures get ids in sequential order when initially placed
        # and the reference_index is positionally linked to the ordered vector of measures.
        measures = session.query(Measures).filter(Measures.pointid == pointid).order_by(Measures.id).all()
        point = session.query(Points).filter(Points.id == pointid).one()
        reference_index = point.reference_index
        t2 = time.time()
        print(f'Query took {t2-t1} seconds to find the measures and reference measure.')
        # Get the reference measure. Previously this was index 0, but now it is a database tracked attribute
        
        # Get the reference measure to instantiate the source node. All other measures will
        # match to the source node.
        source = measures[reference_index]
        reference_index_id = source.imageid

        print(f'Using measure {source.id} on image {source.imageid}/{source.serial} as the reference.')
        print(f'Measure reference index is: {reference_index}')
        source.template_metric = 1
        source.template_shift = 0
        source.phase_error = 0
        source.phase_diff = 0
        source.phase_shift = 0
        
        sourceid = source.imageid
        sourceres = session.query(Images).filter(Images.id == sourceid).one()
        source_node = NetworkNode(node_id=sourceid, image_path=sourceres.path)
        source_node.parent = ncg
        t3 = time.time()
        print(f'Query for the image to use as source took {t3-t2} seconds.')
        print(f'Attempting to subpixel register {len(measures)-1} measures for point {pointid}')
        # Build a node cache so that this is an encapsulated database call. Then nodes
        # can be pulled from the lookup sans database.
        nodes = {}
        for measure in measures:
            res = session.query(Images).filter(Images.id == measure.imageid).one()
            nodes[measure.imageid] = NetworkNode(node_id=measure.imageid, image_path=res.path)
            nn = NetworkNode(node_id=measure.imageid, image_path=res.path)
            nn.parent = ncg
            nodes[measure.imageid] = nn

        session.expunge_all()

    t3 = time.time()
    print(f'Query for the image to use as source took {t3-t2} seconds.')
    print(f'Attempting to subpixel register {len(measures)-1} measures for point {pointid}')
    print(nodes)
    # Set the reference image
    source_node = nodes[reference_index_id]
    
    print(f'Source: sample: {source.sample} | line: {source.line}')
    resultlog = []
    updated_measures = []
    for i, measure in enumerate(measures):
        
        # If this is the reference node, do not attempt to match it.
        if i == reference_index:
            continue

@@ -2270,8 +2275,12 @@ def subpixel_register_point_smart(pointid,
            updated_measures.append([None, None, m])
            continue

        base_roi = img_as_float32(base_roi)
        dst_roi = img_as_float32(dst_roi)

        baseline_mi = mutual_information(base_roi, dst_roi)
        

        # Refactor this call to module
        result = cv2.matchTemplate(base_roi, dst_roi, method=cv2.TM_CCOEFF_NORMED)
        baseline_corr = result[0][0]
@@ -2296,6 +2305,10 @@ def subpixel_register_point_smart(pointid,
            base_roi = roi.Roi(base_arr, source.apriorisample, source.aprioriline, size_x=size_x, size_y=size_y).clip()
            dst_roi = roi.Roi(dst_arr, x, y, size_x=size_x, size_y=size_y).clip()

            #TODO: When refactored, all this type conversion should happen in the ROI object.
            base_roi = img_as_float32(base_roi)
            dst_roi = img_as_float32(dst_roi)

            mi_metric = mutual_information(base_roi, dst_roi)

            if mi_metric is None:
+15 −6
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ def place_points_in_overlaps(size_threshold=0.0007,
    if not ncg.Session:
        raise BrokenPipeError('This func requires a database session from a NetworkCandidateGraph.')

    for overlap in Overlay.overlapping_larger_than(size_threshold, Session):
    for overlap in Overlay.overlapping_larger_than(size_threshold, ncg.Session):
        if overlap.intersections == None:
            continue
        place_points_in_overlap(overlap,
@@ -93,7 +93,7 @@ def place_points_in_overlap(overlap,
                            use_cache=False,
                            **kwargs):
    """
    Place points into an overlap geometry by back-projecing using sensor models.
    Place points into an overlap geometry by back-projecting using sensor models.
    The DEM specified in the config file will be used to calculate point elevations.

    Parameters
@@ -102,7 +102,7 @@ def place_points_in_overlap(overlap,
              An autocnet.io.db.model Overlay model instance.

    identifier: str
                The tag used to distiguish points laid down by this function.
                The tag used to distinguish points laid down by this function.

    cam_type : str
               options: {"csm", "isis"}
@@ -292,16 +292,25 @@ def place_points_in_overlap(overlap,
        # Compute ground point to back project into measurtes
        gnd = csmapi.EcefCoord(x, y, z)

        for node in nodes:
        for current_index, node in enumerate(nodes):
            if cam_type == "csm":
                image_coord = node.camera.groundToImage(gnd)
                sample, line = image_coord.samp, image_coord.line
            if cam_type == "isis":
                # 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
                # to find the most interesting feature.
                try:
                    sample, line = isis.ground_to_image(node["image_path"], updated_lon, updated_lat)
                except CalledProcessError as e:
                    if 'Requested position does not project in camera model' in e.stderr:
                        print(f'interesting point ({updated_lon},{updated_lat}) does not project to image {node["image_path"]}')
                    # If the current_index is greater than the reference_index, the change in list size does
                    # not impact the positional index of the reference. If current_index is less than the
                    # reference_index, then the reference_index needs to de-increment by one for each time
                    # a measure fails to be placed.
                    if current_index < reference_index:
                        reference_index -= 1
                    continue
                    
            point.measures.append(Measures(sample=sample,