Commit 7579ce89 authored by Jay's avatar Jay Committed by Jason R Laura
Browse files

Updates to tests.

parent 52080f2a
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ class TestCamera(unittest.TestCase):
        c = camera.triangulate(coords1, coords2, p, p1)
        np.testing.assert_array_almost_equal(c, truth)

        truth = np.array([ 0.078723,  0.228164,  0.127505,  0.333851,  0.009718])
        c = camera.projection_error(p1, p, coords1, coords2)
        np.testing.assert_array_almost_equal(c, truth)
 No newline at end of file
        truth = np.array([  3.09866357e-02, 2.60295132e-01,
                            8.12871690e-02, 5.57281224e-01,   4.72226586e-04])
        residuals, reproj_error = camera.projection_error(p1, p, coords1, coords2)
        np.testing.assert_array_almost_equal(residuals, truth)
 No newline at end of file
+12 −16
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ from autocnet.utils.utils import find_in_dict
from autocnet.control.control import CorrespondenceNetwork
from autocnet.graph.edge import Edge
from autocnet.graph.node import Node
from autocnet.graph.network import CandidateGraph

sys.path.insert(0, os.path.abspath('..'))

@@ -22,13 +23,15 @@ class TestWriteIsisControlNetwork(unittest.TestCase):
    @classmethod
    def setUpClass(cls):

        cls.npts = 5
        serial_times = {295: '1971-07-31T01:24:11.754',
                        296: '1971-07-31T01:24:36.970'}
        cls.serials = ['APOLLO15/METRIC/{}'.format(i) for i in serial_times.values()]
        net = CandidateGraph({'a': ['b'], 'b': ['a']})
        for i, n in net.nodes_iter(data=True):
            n._keypoints = pd.DataFrame(np.arange(10).reshape(cls.npts,-1), columns=['x', 'y'])
            n._isis_serial = cls.serials[i]

        # Create an edge and a set of matches
        cls.npts = 5
        coords = pd.DataFrame(np.arange(cls.npts * 2).reshape(-1, 2))
        source = np.zeros(cls.npts)
        destination = np.ones(cls.npts)
        pid = np.arange(cls.npts)
@@ -38,19 +41,12 @@ class TestWriteIsisControlNetwork(unittest.TestCase):
                                                                                      'destination_image',
                                                                                      'destination_idx'])

        edge = Mock(spec=Edge)
        edge.source = Mock(spec=Node)
        edge.destination = Mock(spec=Node)
        edge.source.isis_serial = cls.serials[0]
        edge.destination.isis_serial = cls.serials[1]
        edge.source.get_keypoint_coordinates = MagicMock(return_value=coords)
        edge.destination.get_keypoint_coordinates = MagicMock(return_value=coords)

        cnet = CorrespondenceNetwork()
        cnet.add_correspondences(edge, matches)
        cls.creation_date = cnet.creationdate
        cls.modified_date = cnet.modifieddate
        io_controlnetwork.to_isis('test.net', cnet, mode='wb', targetname='Moon')
        net.edge[0][1].matches = matches
        net.generate_cnet(clean_keys=[])

        cls.creation_date = net.creationdate
        cls.modified_date = net.modifieddate
        io_controlnetwork.to_isis('test.net', net, mode='wb', targetname='Moon')

        cls.header_message_size = 98
        cls.point_start_byte = 65634
+29 −9
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ class Edge(dict, MutableMapping):
        mask_lookup = {'fundamental': 'fundamental_matrix',
                       'ratio': 'distance_ratio'}
        if not hasattr(self, '_masks'):
            if hasattr(self, 'matches'):
            if self.matches is not None:
                self._masks = pd.DataFrame(True, columns=['symmetry'],
                                           index=self.matches.index)
            else:
@@ -93,7 +93,21 @@ class Edge(dict, MutableMapping):
        return self._health.health

    def match(self, k=2):
        """
        Given two sets of descriptors, utilize a FLANN (Approximate Nearest
        Neighbor KDTree) matcher to find the k nearest matches.  Nearness is
        the euclidean distance between descriptors.

        The matches are then added as an attribute to the edge object.
        Parameters
        ----------
        k : int
            The number of neighbors to find

        Returns
        -------

        """
        def mono_matches(a, b):
            fl.add(a.descriptors, a.node_id)
            fl.train()
@@ -105,6 +119,15 @@ class Edge(dict, MutableMapping):
        mono_matches(self.destination, self.source)

    def _add_matches(self, matches):
        """
        Given a dataframe of matches, either append to an existing
        matches edge attribute or initially populate said attribute.

        Parameters
        ----------
        matches : dataframe
                  A dataframe of matches
        """
        if self.matches is None:
            self.matches = matches
        else:
@@ -160,6 +183,7 @@ class Edge(dict, MutableMapping):
            return
        matches, mask = self._clean(clean_keys)

        # TODO: Homogeneous is horribly inefficient here, use Numpy array notation
        s_keypoints = self.source.get_keypoint_coordinates(index=matches['source_idx'],
                                                                 homogeneous=True)
        d_keypoints = self.destination.get_keypoint_coordinates(index=matches['destination_idx'],
@@ -219,17 +243,13 @@ class Edge(dict, MutableMapping):
        s_keypoints = self.source.get_keypoint_coordinates(index=matches['source_idx'])
        d_keypoints = self.destination.get_keypoint_coordinates(index=matches['destination_idx'])

        transformation_matrix, ransac_mask = od.compute_homography(s_keypoints.values,
                                                                   d_keypoints.values,
                                                                   **kwargs)
        self.homography = Homography(np.zeros((3,3)), index=self.masks.index)
        self.homography.compute(s_keypoints.values,
                                d_keypoints.values)

        # Convert the truncated RANSAC mask back into a full length mask
        mask[mask] = ransac_mask.ravel()
        mask[mask] = self.homography.mask.ravel()
        self.masks = ('ransac', mask)
        self.homography = Homography(transformation_matrix,
                                     s_keypoints[ransac_mask],
                                     d_keypoints[ransac_mask],
                                     mask=mask[mask].index)

        # Finalize the array to get custom attrs to propagate
        self.homography.__array_finalize__(self.homography)
+1 −2
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@ from autocnet.fileio.io_gdal import GeoDataset
from autocnet.graph import markov_cluster
from autocnet.graph.edge import Edge
from autocnet.graph.node import Node
from autocnet.matcher.add_depth import deepen_correspondences
from autocnet.vis.graph_view import plot_graph


@@ -661,7 +660,7 @@ class CandidateGraph(nx.Graph):
        # get all edges that have matches
        matches = [(u, v) for u, v, edge in self.edges_iter(data=True)
                   if hasattr(edge, 'matches') and
                   not edge.matches.empty]
                   not edge.matches is None]

        return self.create_edge_subgraph(matches)

+13 −13
Original line number Diff line number Diff line
@@ -22,21 +22,31 @@ from autocnet.utils import utils

class Node(dict, MutableMapping):
    """
    This class represents a node in a graph and is synonymous with an
    image.  The node (image) stores PATH information, an accessor to the
    on-disk data set, and correspondences information that references the image.


    Attributes
    ----------

    image_name : str
                 Name of the image, with extension

    image_path : str
                 Relative or absolute PATH to the image

    geodata : object
             File handle to the object

    keypoints : dataframe
                With columns, x, y, and response

    nkeypoints : int
                 The number of keypoints found for this image

    descriptors : ndarray
                  32-bit array of feature descriptors returned by OpenCV

    masks : set
            A list of the available masking arrays

@@ -51,6 +61,7 @@ class Node(dict, MutableMapping):
        self.node_id = node_id
        self._mask_arrays = {}
        self.point_to_correspondence = defaultdict(set)
        self.nkeypoints = 0

    def __repr__(self):
        return """
@@ -69,17 +80,6 @@ class Node(dict, MutableMapping):
            self._geodata = GeoDataset(self.image_path)
        return self._geodata

    @property
    def nkeypoints(self):
        if hasattr(self, '_keypoints'):
            return len(self._keypoints)
        else:
            return 0

    @nkeypoints.setter
    def nkeypoints(self, v):
        self._nkeypoints = v

    @property
    def masks(self):
        mask_lookup = {'suppression': 'suppression'}
@@ -231,7 +231,7 @@ class Node(dict, MutableMapping):
            keypoints[i] = kpt.pt[0], kpt.pt[1], kpt.response, kpt.size, kpt.angle, octave, layer  # y, x
        self._keypoints = pd.DataFrame(keypoints, columns=['x', 'y', 'response', 'size',
                                                           'angle', 'octave', 'layer'])
        self._nkeypoints = len(self._keypoints)
        self.nkeypoints = len(self._keypoints)
        self.descriptors = descriptors.astype(np.float32)

    def load_features(self, in_path):
Loading