Commit efc969bf authored by Laura, Jason R's avatar Laura, Jason R
Browse files

Completes the switch to using a projective transformation

parent 062751ca
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -46,11 +46,14 @@ def test_create_point_with_reference_measure(session):
    point_geom = shapely.Point(0,0,1)
    reference_node = MagicMock()
    reference_node.isis_serial = 'serialnum'
    d = {'node_id':1}

    d = {'node_id':1, 'cam_type':'csm'}
    reference_node.__getitem__.side_effect = d.__getitem__
    sampleline = shapely.Point(1,1)

    point = Points.create_point_with_reference_measure(point_geom, reference_node, sampleline)
    point = Points.create_point_with_reference_measure(point_geom, 
                                                       reference_node, 
                                                       sampleline)

    assert len(point.measures) == 1
    assert point.geom.x == 0
+25 −0
Original line number Diff line number Diff line
@@ -9,6 +9,27 @@ from autocnet.io.geodataset import AGeoDataset

log = logging.getLogger(__name__)

def check_for_excessive_shear(transformation):
    """
    This function checks a skimage projective transform for excessive
    shearing of the data.

    In a projective transformation the final row encodes and adjustment to 
    the vertical/horizontal lines to infinity. The first element u encodes
    a hinging of the along the horizontal and the second element v encodes
    a hinging along the vertical line. As the values approach 0.001 and -0.001
    the amount of shear related distortion (hinging along the horizontal/vertical)
    becomes high enough that matching is problematic as the amount of data
    needed in the templates becomes quite high.
    """
    m = transformation.params
    u = m[2][0]
    v = m[2][1]

    if abs(u) >= 0.001 or abs(v) >= 0.001:
        return True
    return False

def estimate_affine_from_sensors(reference_image,
                                moving_image,
                                bcenter_x,
@@ -136,6 +157,8 @@ def estimate_local_affine(reference_roi, moving_roi):
    # tf_rotate = tf.AffineTransform(rotation=affine_transform.rotation, 
    #                                shear=affine_transform.shear,
    #                                scale=affine_transform.scale)
    # Remove the translation from the transformation. Translation is added below to ensure the
    # transform is centered on the ROI.
    matrix = affine_transform.params
    matrix[0][-1] = 0
    matrix[1][-1] = 0
@@ -154,4 +177,6 @@ def estimate_local_affine(reference_roi, moving_roi):
    # this is 'shift to the center', apply the rotation, shift back
    # to the origin.
    trans = tf_shift_inv + affine_transform + tf_shift
    if check_for_excessive_shear(trans):
        raise Exception(f'Shear Warning: It is highly unlikely that these images will not match, due to differing view geometries.')
    return trans
+25 −12
Original line number Diff line number Diff line
import pytest
import numpy as np
from numpy.testing import assert_array_almost_equal

from autocnet.transformation import affine

from autocnet.transformation import affine, roi
from autocnet.io.geodataset import AGeoDataset
from autocnet.examples import get_path
from skimage.transform import AffineTransform


@pytest.fixture
def g02_ctx():
    return get_path('G02_019154_1800_XN_00N133W.crop.cub')
    return AGeoDataset(get_path('G02_019154_1800_XN_00N133W.crop.cub'), sensortype='isis')

@pytest.fixture
def n06_ctx():
    return get_path('N06_064753_1800_XN_00S133W.crop.cub')
    return AGeoDataset(get_path('N06_064753_1800_XN_00S133W.crop.cub'), sensortype='isis')

@pytest.fixture
def n6_roi(n06_ctx):
    return roi.Roi(n06_ctx, 300,300)

@pytest.fixture
def g02_roi(g02_ctx):
    return roi.Roi(g02_ctx, 100,100)

def test_isis_estimate_affine_transformation(g02_ctx, n06_ctx):
    gd_base = AGeoDataset(g02_ctx, sensortype='isis')
    gd_match = AGeoDataset(n06_ctx, sensortype='isis')
    affine_transform = affine.estimate_affine_from_sensors(gd_base, gd_match, 150, 150)
    assert affine_transform.rotation == pytest.approx(-0.0014690876698891149, 6)
    assert affine_transform.shear == pytest.approx(0.006990455804590304)
    assert affine_transform.scale[0] == pytest.approx(0.99125799, 6)
    assert affine_transform.scale[1] == pytest.approx(0.99840631, 6) 
    assert affine_transform.translation[0] == pytest.approx(-17.03364091, 6)
    assert affine_transform.translation[1] == pytest.approx(49.44769083, 6)
 No newline at end of file
    projective_transform = affine.estimate_affine_from_sensors(g02_ctx, n06_ctx, 150, 150)
    assert_array_almost_equal(projective_transform.params, np.array([[ 9.93968209e-01, -3.54664170e-03, -1.74012988e+01],
                                                                     [-1.13094574e-03,  1.00394116e+00,  4.91146729e+01],
                                                                     [ 1.65323051e-06,  1.51352489e-05,  1.00000000e+00]]))

def test_isis_estimate_local_affine(g02_roi, n6_roi):
    affine_transform = affine.estimate_local_affine(g02_roi, n6_roi)
    assert_array_almost_equal(affine_transform.params, np.array([[ 9.91887398e-01, -9.64539831e-04,  1.86535259e+00],
                                                                 [-1.37864400e-03,  9.99977935e-01,  2.87845656e-01],
                                                                 [ 2.18858798e-07,  5.47986394e-06,  9.98828912e-01]]))
 No newline at end of file
+4 −4
Original line number Diff line number Diff line
@@ -135,11 +135,11 @@ def test_ctx_pair_to_df(session,
    assert measures_to_set_false == []

    m0 = measures_to_update[0]
    assert m0['sample'] == 364.6853301321431
    assert m0['line'] == 525.3395556759572
    assert m0['template_metric'] == 0.6238831281661987
    assert m0['sample'] == 364.68654222552584
    assert m0['line'] == 525.3278698894809
    assert m0['template_metric'] == 0.6234837174415588
    assert m0['ignore'] == False
    assert m0['template_shift'] == 238.67623291833308
    assert m0['template_shift'] == 238.6672416023751

    with mock.patch('pandas.read_sql') as db_response:
        db_cnet = pd.DataFrame([
+8 −8
Original line number Diff line number Diff line
@@ -164,18 +164,18 @@ def test_ctx_pair_to_df(session,
        assert measures_to_set_false == []

        m0 = measures_to_update[0]
        assert m0['sample'] == pytest.approx(764.0473, abs=0.005)
        assert m0['line'] == pytest.approx(1205.976, abs=0.005)
        assert m0['template_metric'] == pytest.approx(0.959, abs=0.01)
        assert m0['sample'] == pytest.approx(764.0510, abs=0.005)
        assert m0['line'] == pytest.approx(1205.9925, abs=0.005)
        assert m0['template_metric'] == pytest.approx(0.962, abs=0.01)
        assert m0['ignore'] == False
        assert m0['template_shift'] == pytest.approx(631.721, abs=0.005)
        assert m0['template_shift'] == pytest.approx(631.730, abs=0.005)
        
        m1 = measures_to_update[1]
        assert m1['sample'] == pytest.approx(843.036, abs=0.005)
        assert m1['line'] == pytest.approx(1547.687, abs=0.005)
        assert m1['template_metric'] == pytest.approx(0.954, abs=0.01)
        assert m1['sample'] == pytest.approx(843.0147, abs=0.005)
        assert m1['line'] == pytest.approx(1547.5938, abs=0.005)
        assert m1['template_metric'] == pytest.approx(0.9578, abs=0.01)
        assert m1['ignore'] == False
        assert m1['template_shift'] == pytest.approx(1006.576, abs=0.005)
        assert m1['template_shift'] == pytest.approx(1006.524, abs=0.005)

        dfs = []
        with mock.patch('pandas.read_sql') as db_response:
Loading