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]

        source = np.zeros(cls.npts)
        destination = np.ones(cls.npts)
        pid = np.arange(cls.npts)

        matches = pd.DataFrame(np.vstack((source, pid, destination, pid)).T, columns=['source_image',
                                                                                      'source_idx',
                                                                                      'destination_image',
                                                                                      'destination_idx'])

        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
def match_images(args, config_dict):
    # Matches the images in the input file using various candidate graph methods
    # produces two files usable in isis

    try:
        cg = CandidateGraph.from_adjacency(find_in_dict(config_dict, 'inputfile_path') +
                                           args.input_file, basepath=find_in_dict(config_dict, 'basepath'))
    except:
        cg = CandidateGraph.from_filelist(find_in_dict(config_dict, 'inputfile_path') + args.input_file)

    # Apply SIFT to extract features
    cg.extract_features(method=config_dict['extract_features']['method'],
                        extractor_parameters=find_in_dict(config_dict, 'extractor_parameters'))

    # Match
    cg.match_features(k=config_dict['match_features']['k'])

    # Apply outlier detection
    cg.apply_func_to_edges('symmetry_check')
    cg.apply_func_to_edges('ratio_check',
                    ratio=find_in_dict(config_dict, 'ratio'),
                    mask_name=find_in_dict(config_dict, 'mask_name'),
                    single=find_in_dict(config_dict, 'single'))

    # Compute a homography and apply RANSAC
    cg.apply_func_to_edges('compute_fundamental_matrix', clean_keys=find_in_dict(config_dict, 'fundamental_matrices')['clean_keys'],
                                    method=find_in_dict(config_dict, 'fundamental_matrices')['method'],
                                    reproj_threshold=find_in_dict(config_dict, 'reproj_threshold'),
                                    confidence=find_in_dict(config_dict, 'confidence'))

    cg.apply_func_to_edges('subpixel_register', clean_keys=find_in_dict(config_dict, 'subpixel_register')['clean_keys'],
                         template_size=find_in_dict(config_dict, 'template_size'),
                         threshold=find_in_dict(config_dict, 'threshold'),
                         search_size=find_in_dict(config_dict, 'search_size'),
                         max_x_shift=find_in_dict(config_dict, 'max_x_shift'),
                         max_y_shift=find_in_dict(config_dict, 'max_y_shift'),
                         tiled=find_in_dict(config_dict, 'tiled'),
                         upsampling = find_in_dict(config_dict, 'upsampling'),
                         error_check = find_in_dict(config_dict, 'error_check'))

    cg.apply_func_to_edges('suppress', clean_keys=find_in_dict(config_dict, 'suppress')['clean_keys'],
                k=find_in_dict(config_dict, 'suppress')['k'],
                min_radius=find_in_dict(config_dict, 'min_radius'),
                error_k=find_in_dict(config_dict, 'error_k'))

    cnet = cg.to_cnet(clean_keys=find_in_dict(config_dict, 'cnet_conversion')['clean_keys'],
                      isis_serials=True)

    filelist = cg.to_filelist()

    write_filelist(filelist, find_in_dict(config_dict, 'outputfile_path') + args.output_file + '.lis')

    to_isis(find_in_dict(config_dict, 'outputfile_path') + args.output_file + '.net', cnet,
            mode='wb',
            networkid=find_in_dict(config_dict, 'networkid'),
            targetname=find_in_dict(config_dict, 'targetname'),
            description=find_in_dict(config_dict, 'description'),
            username=find_in_dict(config_dict, 'username'))
Beispiel #3
0
    def test_two_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('two_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath=basepath)
        assert 2 == cg.number_of_nodes()
        assert 1 == cg.number_of_edges()

        # Step: Extract image data and attribute nodes
        cg.extract_features(extractor_method='vlfeat', extractor_parameters={"nfeatures":500})
        for i, node in cg.nodes.data('data'):
            assert node.nkeypoints in range(5800, 6000)

        # Step: Compute the coverage ratios
        for i, node in cg.nodes.data('data'):
            ratio = node.coverage()
            assert 0.98 < round(ratio, 8) < 0.99
        
        cg.decompose_and_match(k=2, maxiteration=2)
        assert isinstance(cg.edges[0,1]['data'].smembership, np.ndarray)

        # Create fundamental matrix
        cg.compute_fundamental_matrices()

        for s, d, e in cg.edges.data('data'):
            assert isinstance(e.fundamental_matrix, np.ndarray)
            e.compute_fundamental_error(clean_keys=['fundamental'])
            assert 'fundamental_equality' in e.costs.columns
            matches, _ = e.clean(clean_keys=['fundamental'])

        # Apply AMNS
        cg.suppress(k=30, xkey='x', ykey='y', suppression_func=error)

        # Step: Compute subpixel offsets for candidate points
        cg.subpixel_register(clean_keys=['suppression'])
Beispiel #4
0
    def test_three_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('three_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath)
        self.assertEqual(3, cg.number_of_nodes())
        self.assertEqual(3, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(extractor_parameters={'nfeatures':500})
        for i, node, in cg.nodes_iter(data=True):
            self.assertIn(node.nkeypoints, range(490, 511))

        cg.match_features(k=5)
        cg.symmetry_checks()
        cg.ratio_checks()

        cg.apply_func_to_edges("compute_homography", clean_keys=['symmetry', 'ratio'])
        cg.compute_fundamental_matrices(clean_keys=['symmetry', 'ratio'])

        # Step: And create a C object
        cg.generate_cnet(clean_keys=['symmetry', 'ratio', 'ransac'])

        # Step: Create a fromlist to go with the cnet and write it to a file
        filelist = cg.to_filelist()
        write_filelist(filelist, 'TestThreeImageMatching_fromlist.lis')

        # Step: Create a correspondence network
        cg.generate_cnet(clean_keys=['ransac'], deepen=True)

        to_isis('TestThreeImageMatching.net', cg.cn, mode='wb',
                networkid='TestThreeImageMatching', targetname='Moon')
Beispiel #5
0
    def test_two_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('two_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath=basepath)
        self.assertEqual(2, cg.number_of_nodes())
        self.assertEqual(1, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(method='sift', extractor_parameters={"nfeatures":500})
        for i, node in cg.nodes_iter(data=True):
            self.assertIn(node.nkeypoints, range(490, 511))

        # Step: Compute the coverage ratios
        truth_ratios = [0.95351579,
                        0.93595664]
        for i, node in cg.nodes_iter(data=True):
            ratio = node.coverage_ratio()
            self.assertIn(round(ratio, 8), truth_ratios)

        cg.match_features(k=2)

        # Perform the symmetry check
        cg.symmetry_checks()
        # Perform the ratio check
        cg.ratio_checks(clean_keys=['symmetry'], single=True)
        # Create fundamental matrix
        cg.compute_fundamental_matrices(clean_keys = ['symmetry', 'ratio'])

        for source, destination, edge in cg.edges_iter(data=True):

            # Perform the symmetry check
            self.assertIn(edge.masks['symmetry'].sum(), range(400, 600))
            # Perform the ratio test
            self.assertIn(edge.masks['ratio'].sum(), range(225, 275))

            # Range needs to be set
            self.assertIn(edge.masks['fundamental'].sum(), range(200, 250))

        # Step: Compute the homographies and apply RANSAC
        cg.compute_homographies(clean_keys=['symmetry', 'ratio'])

        # Apply AMNS
        cg.suppress(k=30, suppression_func=error)

        # Step: Compute subpixel offsets for candidate points
        cg.subpixel_register(clean_keys=['suppression'])


        # Step: And create a C object
        cg.generate_cnet(clean_keys=['subpixel'])

        # Step: Create a fromlist to go with the cnet and write it to a file
        filelist = cg.to_filelist()
        write_filelist(filelist, path="fromlis.lis")

        # Step: Output a control network
        to_isis('TestTwoImageMatching.net', cg.cn, mode='wb',
                networkid='TestTwoImageMatching', targetname='Moon')
Beispiel #6
0
    def test_two_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('two_image_adjacency.json')
        cg = CandidateGraph.from_adjacency(adjacency)
        self.assertEqual(2, cg.number_of_nodes())
        self.assertEqual(1, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(extractor_parameters={"nfeatures":500})
        for node, attributes in cg.nodes_iter(data=True):
            self.assertIn(len(attributes['keypoints']), range(490, 511))

        # Step: Then apply a FLANN matcher
        fl = FlannMatcher()
        for node, attributes in cg.nodes_iter(data=True):
            fl.add(attributes['descriptors'], key=node)
        fl.train()

        for node, attributes in cg.nodes_iter(data=True):
            descriptors = attributes['descriptors']
            matches = fl.query(descriptors, node, k=5)
            cg.add_matches(matches)

        for source, destination, attributes in cg.edges_iter(data=True):
            matches = attributes['matches']
            # Perform the symmetry check
            symmetry_mask = od.mirroring_test(matches)
            self.assertIn(symmetry_mask.sum(), range(430, 461))
            attributes['symmetry'] = symmetry_mask

            # Perform the ratio test
            ratio_mask = od.distance_ratio(matches, ratio=0.95)
            self.assertIn(ratio_mask.sum(), range(390, 451))
            attributes['ratio'] = ratio_mask

            mask = np.array(ratio_mask * symmetry_mask)
            self.assertIn(len(matches.loc[mask]), range(75,101))

        # Step: Compute the homographies and apply RANSAC
        cg.compute_homographies(clean_keys=['symmetry', 'ratio'])

        # Step: Compute subpixel offsets for candidate points
        cg.compute_subpixel_offsets(clean_keys=['symmetry', 'ratio', 'ransac'])

        # Step: And create a C object
        cnet = cg.to_cnet(clean_keys=['symmetry', 'ratio', 'ransac', 'subpixel'])
        # Step update the serial numbers
        nid_to_serial = {}
        for node, attributes in cg.nodes_iter(data=True):
            nid_to_serial[node] = self.serial_numbers[attributes['image_name']]

        cnet.replace({'nid': nid_to_serial}, inplace=True)

        # Step: Output a control network
        to_isis('TestTwoImageMatching.net', cnet, mode='wb',
                networkid='TestTwoImageMatching', targetname='Moon')
    def test_coverage(self):
        adjacency = get_path('two_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath=basepath)
        keypoint_df = pd.DataFrame({'x': (15, 18, 18, 12, 12), 'y': (5, 10, 15, 15, 10)})
        keypoint_matches = [[0, 0, 1, 0],
                            [0, 1, 1, 1],
                            [0, 2, 1, 2],
                            [0, 3, 1, 3],
                            [0, 4, 1, 4]]

        matches_df = pd.DataFrame(data = keypoint_matches, columns = ['source_image', 'source_idx', 'destination_image', 'destination_idx'])
        e = edge.Edge()
        source_node = MagicMock(spec = node.Node())
        destination_node = MagicMock(spec = node.Node())

        source_node.get_keypoint_coordinates = MagicMock(return_value=keypoint_df)
        destination_node.get_keypoint_coordinates = MagicMock(return_value=keypoint_df)

        e.source = source_node
        e.destination = destination_node

        source_geodata = Mock(spec = io_gdal.GeoDataset)
        destination_geodata = Mock(spec = io_gdal.GeoDataset)

        e.source.geodata = source_geodata
        e.destination.geodata = destination_geodata

        source_corners = [(0, 0),
                          (20, 0),
                          (20, 20),
                          (0, 20)]

        destination_corners = [(10, 5),
                               (30, 5),
                               (30, 25),
                               (10, 25)]

        e.source.geodata.latlon_corners = source_corners
        e.destination.geodata.latlon_corners = destination_corners

        vals = {(15, 5):(15, 5), (18, 10):(18, 10), (18, 15):(18, 15), (12, 15):(12, 15), (12, 10):(12, 10)}

        def pixel_to_latlon(i, j):
            return vals[(i, j)]

        e.source.geodata.pixel_to_latlon = MagicMock(side_effect = pixel_to_latlon)
        e.destination.geodata.pixel_to_latlon = MagicMock(side_effect = pixel_to_latlon)

        e.matches = matches_df

        self.assertRaises(AttributeError, cg.edge[0][1].coverage)
        self.assertEqual(e.coverage(), 0.3)
Beispiel #8
0
    def test_two_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path("two_image_adjacency.json")
        cg = CandidateGraph.from_adjacency(adjacency)
        self.assertEqual(2, cg.number_of_nodes())
        self.assertEqual(1, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(500)
        for node, attributes in cg.nodes_iter(data=True):
            self.assertIn(len(attributes["keypoints"]), range(490, 511))

        # Step: Then apply a FLANN matcher
        fl = FlannMatcher()
        for node, attributes in cg.nodes_iter(data=True):
            fl.add(attributes["descriptors"], key=node)
        fl.train()

        for node, attributes in cg.nodes_iter(data=True):
            descriptors = attributes["descriptors"]
            matches = fl.query(descriptors, node, k=5)
            cg.add_matches(matches)

        for source, destination, attributes in cg.edges_iter(data=True):
            matches = attributes["matches"]
            # Perform the symmetry check
            symmetry_mask = od.mirroring_test(matches)
            self.assertIn(symmetry_mask.sum(), range(430, 461))
            attributes["symmetry"] = symmetry_mask

            # Perform the ratio test
            ratio_mask = od.distance_ratio(matches, ratio=0.95)
            self.assertIn(ratio_mask.sum(), range(400, 451))
            attributes["ratio"] = ratio_mask

            mask = np.array(ratio_mask * symmetry_mask)
            self.assertIn(len(matches.loc[mask]), range(75, 101))

            cg.compute_homographies(clean_keys=["symmetry", "ratio"])

        # Step: And create a C object
        cnet = cg.to_cnet(clean_keys=["symmetry", "ratio", "ransac"])
        # Step update the serial numbers
        nid_to_serial = {}
        for node, attributes in cg.nodes_iter(data=True):
            nid_to_serial[node] = self.serial_numbers[attributes["image_name"]]

        cnet.replace({"nid": nid_to_serial}, inplace=True)

        # Step: Output a control network
        to_isis("TestTwoImageMatching.net", cnet, mode="wb", networkid="TestTwoImageMatching", targetname="Moon")
Beispiel #9
0
def candidategraph(node_a, node_b, node_c):
    # TODO: Getting this fixture from the global conf is causing deepycopy
    # to fail.  Why?
    cg = CandidateGraph()

    # Create a candidategraph object - we instantiate a real CandidateGraph to
    # have access of networkx functionality we do not want to test and then
    # mock all autocnet functionality to control test behavior.
    edges = [(0, 1, {
        'data': edge.Edge(0, 1)
    }), (0, 2, {
        'data': edge.Edge(0, 2)
    }), (1, 2, {
        'data': edge.Edge(1, 2)
    })]

    cg.add_edges_from(edges)

    match_indices = [([0, 1, 2, 3, 4, 5, 6, 7], [0, 1, 2, 3, 4, 5, 6, 7]),
                     ([0, 1, 2, 3, 4, 5, 8, 9], [0, 1, 2, 3, 4, 5, 8, 9]),
                     ([0, 1, 2, 3, 4, 5, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7])]

    matches = []
    for i, e in enumerate(edges):
        c = match_indices[i]
        source_image = np.repeat(e[0], 8)
        destin_image = np.repeat(e[1], 8)
        coords = np.zeros(8)
        data = np.vstack((source_image, c[0], destin_image, c[1], coords,
                          coords, coords, coords)).T
        matches_df = pd.DataFrame(data,
                                  columns=[
                                      'source_image', 'source_idx',
                                      'destination_image', 'destination_idx',
                                      'source_x', 'source_y', 'destination_x',
                                      'destination_y'
                                  ])
        matches.append(matches_df)

    # Mock in autocnet methods
    cg.get_matches = MagicMock(return_value=matches)

    # Mock in the node objects onto the candidate graph
    cg.node[0]['data'] = node_a
    cg.node[1]['data'] = node_b
    cg.node[2]['data'] = node_c

    return cg
    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]

        source = np.zeros(cls.npts)
        destination = np.ones(cls.npts)
        pid = np.arange(cls.npts)

        matches = pd.DataFrame(np.vstack((source, pid, destination, pid)).T,
                               columns=[
                                   'source_image', 'source_idx',
                                   'destination_image', 'destination_idx'
                               ])

        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
Beispiel #11
0
    def test_three_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('three_image_adjacency.json')
        cg = CandidateGraph.from_adjacency(adjacency)
        self.assertEqual(3, cg.number_of_nodes())
        self.assertEqual(3, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(extractor_parameters={'nfeatures':500})
        for node, attributes in cg.nodes_iter(data=True):
            self.assertIn(len(attributes['keypoints']), range(490, 511))

        fl = FlannMatcher()
        for node, attributes in cg.nodes_iter(data=True):
            fl.add(attributes['descriptors'], key=node)
        fl.train()

        for node, attributes in cg.nodes_iter(data=True):
            descriptors = attributes['descriptors']
            matches = fl.query(descriptors, node, k=5)
            cg.add_matches(matches)

        for source, destination, attributes in cg.edges_iter(data=True):
            matches = attributes['matches']
            # Perform the symmetry check
            symmetry_mask = od.mirroring_test(matches)
            attributes['symmetry'] = symmetry_mask

            # Perform the ratio test
            ratio_mask = od.distance_ratio(matches, ratio=0.8)
            attributes['ratio'] = ratio_mask

        cg.compute_homographies(clean_keys=['symmetry', 'ratio'])

        # Step: And create a C object
        cnet = cg.to_cnet(clean_keys=['symmetry', 'ratio', 'ransac'])

        # Step update the serial numbers
        nid_to_serial = {}
        for node, attributes in cg.nodes_iter(data=True):
            nid_to_serial[node] = self.serial_numbers[attributes['image_name']]

        cnet.replace({'nid': nid_to_serial}, inplace=True)
        # Step: Output a control network
        to_isis('TestThreeImageMatching.net', cnet, mode='wb',
                networkid='TestThreeImageMatching', targetname='Moon')
Beispiel #12
0
    def test_cpu_match(self):
        # Build a graph
        adjacency = get_path('two_image_adjacency.json')
        basepath = get_path('Apollo15')
        cang = CandidateGraph.from_adjacency(adjacency, basepath=basepath)

        # Extract features
        cang.extract_features(extractor_parameters={'nfeatures': 700})

        # Make sure cpu matcher is used for test
        edges = list()
        from autocnet.matcher.cpu_matcher import match as match
        for s, d in cang.edges():
            cang[s][d]['data']._match = match
            edges.append(cang[s][d])

        # Assert none of the edges have masks yet
        for edge in edges:
            self.assertTrue(edge['data'].masks.empty)

        # Match & outlier detect
        cang.match()
        cang.symmetry_checks()

        # Grab the length of a matches df
        match_len = len(edges[0]['data'].matches.index)

        # Assert symmetry check is now in all edge masks
        for edge in edges:
            self.assertTrue('symmetry' in edge['data'].masks)

        # Assert matches have been populated
        for edge in edges:
            self.assertTrue(not edge['data'].matches.empty)

        # Re-match
        cang.match()

        # Assert that new matches have been added on to old ones
        self.assertEqual(len(edges[0]['data'].matches.index), match_len * 2)

        # Assert that the match cleared the masks df
        for edge in edges:
            self.assertTrue(edge['data'].masks.empty)
Beispiel #13
0
    def test_three_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('three_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath)
        self.assertEqual(3, cg.number_of_nodes())
        self.assertEqual(3, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(extractor_parameters={'nfeatures': 500})
        for i, node, in cg.nodes_iter(data=True):
            self.assertIn(node.nkeypoints, range(490, 511))

        cg.match_features(k=5)

        for source, destination, edge in cg.edges_iter(data=True):
            matches = edge.matches
            edge.symmetry_check()
            edge.ratio_check(ratio=0.8)

        cg.compute_homographies(clean_keys=['symmetry', 'ratio'])

        # Step: And create a C object
        cnet = cg.to_cnet(clean_keys=['symmetry', 'ratio', 'ransac'])

        # Step: Create a fromlist to go with the cnet and write it to a file
        filelist = cg.to_filelist()
        write_filelist(filelist, 'TestThreeImageMatching_fromlist.lis')

        # Step update the serial numbers
        nid_to_serial = {}
        for i, node in cg.nodes_iter(data=True):
            nid_to_serial[i] = self.serial_numbers[node.image_name]

        cnet.replace({'nid': nid_to_serial}, inplace=True)
        # Step: Output a control network
        to_isis('TestThreeImageMatching.net',
                cnet,
                mode='wb',
                networkid='TestThreeImageMatching',
                targetname='Moon')
Beispiel #14
0
    def test_three_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('three_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath=basepath)
        self.assertEqual(3, cg.number_of_nodes())
        self.assertEqual(3, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(extractor_method='vlfeat')
        for i, node, in cg.nodes_iter(data=True):
            self.assertIn(node.nkeypoints, range(5800, 6000))

        cg.match(k=2)
        cg.symmetry_checks()
        cg.ratio_checks()

        cg.apply_func_to_edges("compute_homography", clean_keys=['symmetry', 'ratio'])
        for s, d, e in cg.edges_iter(data=True):
            self.assertTrue('homography' in e.keys())
        cg.compute_fundamental_matrices(clean_keys=['symmetry', 'ratio'], reproj_threshold=3.0, method='ransac')
Beispiel #15
0
def candidategraph():
    a = '/fake_path/a.img'
    b = '/fake_path/b.img'
    c = '/fake_path/c.img'
    adj = {a:[b,c],
           b:[a,c],
           c:[a, b]}
    cg = CandidateGraph.from_adjacency(adj)

    match_data = np.array([[0.0,	188.0,	1.0, 0.0, 170.754211],
                           [0.0,	189.0,	1.0, 0.0, 217.451141],
                           [0.0,	185.0,	1.0, 1.0, 108.843925]])
    matches = pd.DataFrame(match_data, columns=['source_image', 'source_idx',
                                                'destination_image', 'destination_idx',
                                                'distance'])
    masks = pd.DataFrame([[True, True],
                          [False, True],
                          [True, False]],
                          columns=['rain', 'maker'])

    for s, d, e in cg.edges.data('data'):
        e['fundamental_matrix'] = np.random.random(size=(3,3))
        e.matches = matches
        e.masks = masks
        e['source_mbr'] = [[0,1], [0,2]]
        e['destin_mbr'] = [[0.5, 0.5], [1, 1]]

    kps = np.array([[233.358475,	105.288162,	0.035672, 4.486887,	164.181046,	0.0, 1.0],
                    [366.288116,	98.761131,	0.035900, 4.158592,	147.278580,	0.0, 1.0],
                    [170.932114,	114.173912,	0.037852, 94.446655, 0.401794,	0.0, 3.0]])

    keypoints = pd.DataFrame(kps, columns=['x', 'y', 'response', 'size', 'angle',
                                           'octave', 'layer'])

    for i, n in cg.nodes.data('data'):
        n.keypoints = keypoints
        n.descriptors = np.random.random(size=(3, 128))
        n.masks = masks

    return cg
    def test_three_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('three_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath)
        self.assertEqual(3, cg.number_of_nodes())
        self.assertEqual(3, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(extractor_parameters={'nfeatures': 500})
        for i, node, in cg.nodes_iter(data=True):
            self.assertIn(node.nkeypoints, range(490, 511))

        cg.match_features(k=5)

        for source, destination, edge in cg.edges_iter(data=True):
            edge.symmetry_check()
            edge.ratio_check(clean_keys=['symmetry'], ratio=0.99)

        cg.apply_func_to_edges("compute_homography",
                               clean_keys=['symmetry', 'ratio'])
        cg.compute_fundamental_matrices(clean_keys=['symmetry', 'ratio'])

        # Step: And create a C object
        cg.generate_cnet(clean_keys=['symmetry', 'ratio', 'ransac'])

        # Step: Create a fromlist to go with the cnet and write it to a file
        filelist = cg.to_filelist()
        write_filelist(filelist, 'TestThreeImageMatching_fromlist.lis')

        # Step: Create a correspondence network
        cg.generate_cnet(clean_keys=['symmetry', 'ratio', 'ransac'],
                         deepen=True)

        to_isis('TestThreeImageMatching.net',
                cg,
                mode='wb',
                networkid='TestThreeImageMatching',
                targetname='Moon')
Beispiel #17
0
def candidategraph(node_a, node_b, node_c):
    # TODO: Getting this fixture from the global conf is causing deepycopy
    # to fail.  Why?
    cg = CandidateGraph()

    # Create a candidategraph object - we instantiate a real CandidateGraph to
    # have access of networkx functionality we do not want to test and then
    # mock all autocnet functionality to control test behavior.
    edges = [(0,1,{'data':edge.Edge(0,1)}),
             (0,2,{'data':edge.Edge(0,2)}),
             (1,2,{'data':edge.Edge(1,2)})]

    cg.add_edges_from(edges)



    match_indices = [([0,1,2,3,4,5,6,7], [0,1,2,3,4,5,6,7]),
                     ([0,1,2,3,4,5,8,9], [0,1,2,3,4,5,8,9]),
                     ([0,1,2,3,4,5,8,9], [0,1,2,3,4,5,6,7])]

    matches = []
    for i, e in enumerate(edges):
        c = match_indices[i]
        source_image = np.repeat(e[0], 8)
        destin_image = np.repeat(e[1], 8)
        coords = np.zeros(8)
        data = np.vstack((source_image, c[0], destin_image, c[1],
                          coords, coords, coords, coords)).T
        matches_df = pd.DataFrame(data, columns=['source_image', 'source_idx', 'destination_image', 'destination_idx',
                                                 'source_x', 'source_y', 'destination_x', 'destination_y'])
        matches.append(matches_df)

    # Mock in autocnet methods
    cg.get_matches = MagicMock(return_value=matches)

    # Mock in the node objects onto the candidate graph
    cg.node[0]['data'] = node_a
    cg.node[1]['data'] = node_b
    cg.node[2]['data'] = node_c

    return cg
Beispiel #18
0
    def test_three_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('three_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath)
        self.assertEqual(3, cg.number_of_nodes())
        self.assertEqual(3, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(extractor_parameters={'nfeatures':500})
        for i, node, in cg.nodes_iter(data=True):
            self.assertIn(node.nkeypoints, range(490, 511))

        cg.match_features(k=5)

        for source, destination, edge in cg.edges_iter(data=True):
            matches = edge.matches
            edge.symmetry_check()
            edge.ratio_check(ratio=0.8)

        cg.compute_homographies(clean_keys=['symmetry', 'ratio'])

        # Step: And create a C object
        cnet = cg.to_cnet(clean_keys=['symmetry', 'ratio', 'ransac'])

        # Step: Create a fromlist to go with the cnet and write it to a file
        filelist = cg.to_filelist()
        write_filelist(filelist, 'TestThreeImageMatching_fromlist.lis')

        # Step update the serial numbers
        nid_to_serial = {}
        for i, node in cg.nodes_iter(data=True):
            nid_to_serial[i] = self.serial_numbers[node.image_name]

        cnet.replace({'nid': nid_to_serial}, inplace=True)
        # Step: Output a control network
        to_isis('TestThreeImageMatching.net', cnet, mode='wb',
                networkid='TestThreeImageMatching', targetname='Moon')
Beispiel #19
0
    def test_two_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('two_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath=basepath)
        self.assertEqual(2, cg.number_of_nodes())
        self.assertEqual(1, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(extractor_method='sift',
                            extractor_parameters={"nfeatures": 500})
        for i, node in cg.nodes.data('data'):
            self.assertIn(node.nkeypoints, range(490, 510))

        # Step: Compute the coverage ratios
        for i, node in cg.nodes.data('data'):
            ratio = node.coverage()
            self.assertTrue(0.93 < round(ratio, 8) < 0.96)

        cg.decompose_and_match(k=2, maxiteration=2)
        self.assertTrue(
            isinstance(cg.edges[0, 1]['data'].smembership, np.ndarray))

        # Create fundamental matrix
        cg.compute_fundamental_matrices()

        for s, d, e in cg.edges.data('data'):
            assert isinstance(e.fundamental_matrix, np.ndarray)
            e.compute_fundamental_error(clean_keys=['fundamental'])
            assert 'fundamental_equality' in e.costs.columns
            matches, _ = e.clean(clean_keys=['fundamental'])

        # Apply AMNS
        cg.suppress(k=30, xkey='x', ykey='y', suppression_func=error)

        # Step: Compute subpixel offsets for candidate points
        cg.subpixel_register(clean_keys=['suppression'])
Beispiel #20
0
    def test_three_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path("three_image_adjacency.json")
        basepath = get_path("Apollo15")
        cg = CandidateGraph.from_adjacency(adjacency, basepath)
        self.assertEqual(3, cg.number_of_nodes())
        self.assertEqual(3, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(extractor_parameters={"nfeatures": 500})
        for i, node in cg.nodes_iter(data=True):
            self.assertIn(node.nkeypoints, range(490, 511))

        cg.match_features(k=5)

        for source, destination, edge in cg.edges_iter(data=True):
            edge.symmetry_check()
            edge.ratio_check(clean_keys=["symmetry"], ratio=0.99)

        cg.apply_func_to_edges("compute_homography", clean_keys=["symmetry", "ratio"])

        # Step: And create a C object
        cnet = cg.to_cnet(clean_keys=["symmetry", "ratio", "ransac"])

        # Step: Create a fromlist to go with the cnet and write it to a file
        filelist = cg.to_filelist()
        write_filelist(filelist, "TestThreeImageMatching_fromlist.lis")

        # Step update the serial numbers
        nid_to_serial = {}
        for i, node in cg.nodes_iter(data=True):
            nid_to_serial[i] = self.serial_numbers[node.image_name]

        cnet.replace({"nid": nid_to_serial}, inplace=True)
        # Step: Output a control network
        to_isis("TestThreeImageMatching.net", cnet, mode="wb", networkid="TestThreeImageMatching", targetname="Moon")
Beispiel #21
0
    def test_three_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('three_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath=basepath)
        self.assertEqual(3, cg.number_of_nodes())
        self.assertEqual(3, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(extractor_parameters={'nfeatures': 500})
        for i, node, in cg.nodes_iter(data=True):
            self.assertIn(node.nkeypoints, range(490, 511))

        cg.match(k=2)
        cg.symmetry_checks()
        cg.ratio_checks()

        cg.apply_func_to_edges("compute_homography",
                               clean_keys=['symmetry', 'ratio'])
        for s, d, e in cg.edges_iter(data=True):
            self.assertTrue('homography' in e.keys())
        cg.compute_fundamental_matrices(clean_keys=['symmetry', 'ratio'],
                                        reproj_threshold=3.0,
                                        method='ransac')
Beispiel #22
0
def match_images(args, config_dict):
    # Matches the images in the input file using various candidate graph methods
    # produces two files usable in isis

    try:
        cg = CandidateGraph.from_adjacency(
            find_in_dict(config_dict, 'inputfile_path') + args.input_file,
            basepath=find_in_dict(config_dict, 'basepath'))
    except:
        cg = CandidateGraph.from_filelist(
            find_in_dict(config_dict, 'inputfile_path') + args.input_file)

    # Apply SIFT to extract features
    cg.extract_features(method=config_dict['extract_features']['method'],
                        extractor_parameters=find_in_dict(
                            config_dict, 'extractor_parameters'))

    # Match
    cg.match_features(k=config_dict['match_features']['k'])

    # Apply outlier detection
    cg.apply_func_to_edges('symmetry_check')
    cg.apply_func_to_edges('ratio_check',
                           ratio=find_in_dict(config_dict, 'ratio'),
                           mask_name=find_in_dict(config_dict, 'mask_name'),
                           single=find_in_dict(config_dict, 'single'))

    # Compute a homography and apply RANSAC
    cg.apply_func_to_edges(
        'compute_fundamental_matrix',
        clean_keys=find_in_dict(config_dict,
                                'fundamental_matrices')['clean_keys'],
        method=find_in_dict(config_dict, 'fundamental_matrices')['method'],
        reproj_threshold=find_in_dict(config_dict, 'reproj_threshold'),
        confidence=find_in_dict(config_dict, 'confidence'))

    cg.apply_func_to_edges(
        'subpixel_register',
        clean_keys=find_in_dict(config_dict,
                                'subpixel_register')['clean_keys'],
        template_size=find_in_dict(config_dict, 'template_size'),
        threshold=find_in_dict(config_dict, 'threshold'),
        search_size=find_in_dict(config_dict, 'search_size'),
        max_x_shift=find_in_dict(config_dict, 'max_x_shift'),
        max_y_shift=find_in_dict(config_dict, 'max_y_shift'),
        tiled=find_in_dict(config_dict, 'tiled'),
        upsampling=find_in_dict(config_dict, 'upsampling'),
        error_check=find_in_dict(config_dict, 'error_check'))

    cg.apply_func_to_edges('suppress',
                           clean_keys=find_in_dict(config_dict,
                                                   'suppress')['clean_keys'],
                           k=find_in_dict(config_dict, 'suppress')['k'],
                           min_radius=find_in_dict(config_dict, 'min_radius'),
                           error_k=find_in_dict(config_dict, 'error_k'))

    cnet = cg.to_cnet(clean_keys=find_in_dict(config_dict,
                                              'cnet_conversion')['clean_keys'],
                      isis_serials=True)

    filelist = cg.to_filelist()

    write_filelist(
        filelist,
        find_in_dict(config_dict, 'outputfile_path') + args.output_file +
        '.lis')

    to_isis(find_in_dict(config_dict, 'outputfile_path') + args.output_file +
            '.net',
            cnet,
            mode='wb',
            networkid=find_in_dict(config_dict, 'networkid'),
            targetname=find_in_dict(config_dict, 'targetname'),
            description=find_in_dict(config_dict, 'description'),
            username=find_in_dict(config_dict, 'username'))
Beispiel #23
0
    def test_two_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('two_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath=basepath)
        self.assertEqual(2, cg.number_of_nodes())
        self.assertEqual(1, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(method='sift', extractor_parameters={"nfeatures":500})
        for i, node in cg.nodes_iter(data=True):
            self.assertIn(node.nkeypoints, range(490, 511))

        #Step: Compute the coverage ratios
        truth_ratios = [0.95351579,
                        0.93595664]
        for i, node in cg.nodes_iter(data=True):
            ratio = node.coverage_ratio()
            self.assertIn(round(ratio,8), truth_ratios)
        # Step: apply Adaptive non-maximal suppression
        for i, node in cg.nodes_iter(data=True):
            pass
            #node.anms()
            #self.assertNotEqual(node.nkeypoints, sum(node._mask_arrays['anms']))

        cg.match_features(k=5)

        for source, destination, edge in cg.edges_iter(data=True):

            # Perform the symmetry check
            edge.symmetry_check()
            self.assertIn(edge._mask_arrays['symmetry'].sum(), range(430, 461))

            # Perform the ratio test
            edge.ratio_check(ratio=0.8)
            self.assertIn(edge._mask_arrays['ratio'].sum(), range(250, 350))

        # Step: Compute the homographies and apply RANSAC
        cg.compute_homographies(clean_keys=['symmetry', 'ratio'])

        # Step: Compute the overlap ratio and coverage ratio
        for s, d, edge in cg.edges_iter(data=True):
            ratio = edge.coverage_ratio(clean_keys=['symmetry', 'ratio'])

        # Step: Compute subpixel offsets for candidate points
        cg.compute_subpixel_offsets(clean_keys=['ransac'])

        # Step: And create a C object
        cnet = cg.to_cnet(clean_keys=['symmetry', 'ratio', 'ransac', 'subpixel'])

        # Step: Create a fromlist to go with the cnet and write it to a file
        filelist = cg.to_filelist()
        write_filelist(filelist, path="fromlis.lis")

        # Step update the serial numbers
        nid_to_serial = {}
        for i, node in cg.nodes_iter(data=True):
            nid_to_serial[i] = self.serial_numbers[node.image_name]

        cnet.replace({'nid': nid_to_serial}, inplace=True)
        # Step: Output a control network
        to_isis('TestTwoImageMatching.net', cnet, mode='wb',
                networkid='TestTwoImageMatching', targetname='Moon')
    def test_two_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('two_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath=basepath)
        self.assertEqual(2, cg.number_of_nodes())
        self.assertEqual(1, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(method='sift', extractor_parameters={"nfeatures":500})
        for i, node in cg.nodes_iter(data=True):
            self.assertIn(node.nkeypoints, range(490, 511))

        #Step: Compute the coverage ratios
        truth_ratios = [0.95351579,
                        0.93595664]
        for i, node in cg.nodes_iter(data=True):
            ratio = node.coverage_ratio()
            self.assertIn(round(ratio,8), truth_ratios)
        # Step: apply Adaptive non-maximal suppression
        for i, node in cg.nodes_iter(data=True):
            pass
            #node.anms()
            #self.assertNotEqual(node.nkeypoints, sum(node._mask_arrays['anms']))

        cg.match_features(k=5)

        for source, destination, edge in cg.edges_iter(data=True):

            # Perform the symmetry check
            edge.symmetry_check()
            self.assertIn(edge.masks['symmetry'].sum(), range(430, 461))

            # Perform the ratio test
            edge.ratio_check(ratio=0.9, clean_keys=['symmetry'])
            self.assertIn(edge.masks['ratio'].sum(), range(25, 50))

        # Step: Compute the homographies and apply RANSAC
        cg.compute_homographies(clean_keys=['symmetry', 'ratio'])

        # Step: Compute the overlap ratio and coverage ratio
        for s, d, edge in cg.edges_iter(data=True):
            ratio = edge.coverage_ratio(clean_keys=['symmetry', 'ratio'])

        # Step: Compute subpixel offsets for candidate points
        cg.subpixel_register(clean_keys=['ransac'])

        # Step: And create a C object
        cnet = cg.to_cnet(clean_keys=['symmetry', 'ratio', 'ransac', 'subpixel'])

        # Step: Create a fromlist to go with the cnet and write it to a file
        filelist = cg.to_filelist()
        write_filelist(filelist, path="fromlis.lis")

        # Step update the serial numbers
        nid_to_serial = {}
        for i, node in cg.nodes_iter(data=True):
            nid_to_serial[i] = self.serial_numbers[node.image_name]

        cnet.replace({'nid': nid_to_serial}, inplace=True)
        # Step: Output a control network
        to_isis('TestTwoImageMatching.net', cnet, mode='wb',
                networkid='TestTwoImageMatching', targetname='Moon')
Beispiel #25
0
 def new(self):
     self.cg = CandidateGraph()
     return 'success'
 def setUp(self):
     self.g = CandidateGraph.from_graph(get_path('sixty_four_apollo.graph'))
Beispiel #27
0
 def setUp(self):
     self.g = CandidateGraph.from_graph(get_path('sixty_four_apollo.graph'))
Beispiel #28
0
    def test_coverage(self):
        adjacency = get_path('two_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath=basepath)
        keypoint_df = pd.DataFrame({
            'x': (15, 18, 18, 12, 12),
            'y': (5, 10, 15, 15, 10)
        })
        keypoint_matches = [[0, 0, 1, 0], [0, 1, 1, 1], [0, 2, 1, 2],
                            [0, 3, 1, 3], [0, 4, 1, 4]]

        matches_df = pd.DataFrame(data=keypoint_matches,
                                  columns=[
                                      'source_image', 'source_idx',
                                      'destination_image', 'destination_idx'
                                  ])
        e = edge.Edge()
        source_node = MagicMock(spec=node.Node())
        destination_node = MagicMock(spec=node.Node())

        source_node.get_keypoint_coordinates = MagicMock(
            return_value=keypoint_df)
        destination_node.get_keypoint_coordinates = MagicMock(
            return_value=keypoint_df)

        e.source = source_node
        e.destination = destination_node

        source_geodata = Mock(spec=io_gdal.GeoDataset)
        destination_geodata = Mock(spec=io_gdal.GeoDataset)

        e.source.geodata = source_geodata
        e.destination.geodata = destination_geodata

        source_corners = [(0, 0), (20, 0), (20, 20), (0, 20)]

        destination_corners = [(10, 5), (30, 5), (30, 25), (10, 25)]

        e.source.geodata.latlon_corners = source_corners
        e.destination.geodata.latlon_corners = destination_corners

        vals = {
            (15, 5): (15, 5),
            (18, 10): (18, 10),
            (18, 15): (18, 15),
            (12, 15): (12, 15),
            (12, 10): (12, 10)
        }

        def pixel_to_latlon(i, j):
            return vals[(i, j)]

        e.source.geodata.pixel_to_latlon = MagicMock(
            side_effect=pixel_to_latlon)
        e.destination.geodata.pixel_to_latlon = MagicMock(
            side_effect=pixel_to_latlon)

        e.matches = matches_df

        self.assertRaises(AttributeError, cg.edge[0][1].coverage)
        self.assertEqual(e.coverage(), 0.3)
Beispiel #29
0
    def test_two_image(self):
        # Step: Create an adjacency graph
        adjacency = get_path('two_image_adjacency.json')
        basepath = get_path('Apollo15')
        cg = CandidateGraph.from_adjacency(adjacency, basepath=basepath)
        self.assertEqual(2, cg.number_of_nodes())
        self.assertEqual(1, cg.number_of_edges())

        # Step: Extract image data and attribute nodes
        cg.extract_features(method='sift',
                            extractor_parameters={"nfeatures": 500})
        for i, node in cg.nodes_iter(data=True):
            self.assertIn(node.nkeypoints, range(490, 511))

        # Step: Compute the coverage ratios
        truth_ratios = [0.95351579, 0.93595664]
        for i, node in cg.nodes_iter(data=True):
            ratio = node.coverage_ratio()
            self.assertIn(round(ratio, 8), truth_ratios)

        cg.match_features(k=2)

        # Perform the symmetry check
        cg.symmetry_checks()
        # Perform the ratio check
        cg.ratio_checks(clean_keys=['symmetry'], single=True)
        # Create fundamental matrix
        cg.compute_fundamental_matrices(clean_keys=['symmetry', 'ratio'])

        for source, destination, edge in cg.edges_iter(data=True):

            # Perform the symmetry check
            self.assertIn(edge.masks['symmetry'].sum(), range(400, 600))
            # Perform the ratio test
            self.assertIn(edge.masks['ratio'].sum(), range(225, 275))

            # Range needs to be set
            self.assertIn(edge.masks['fundamental'].sum(), range(200, 250))

        # Step: Compute the homographies and apply RANSAC
        cg.compute_homographies(clean_keys=['symmetry', 'ratio'])

        # Apply AMNS
        cg.suppress(k=30, suppression_func=error)

        # Step: Compute subpixel offsets for candidate points
        cg.subpixel_register(clean_keys=['suppression'])

        # Step: And create a C object
        cg.generate_cnet(clean_keys=['subpixel'])

        # Step: Create a fromlist to go with the cnet and write it to a file
        filelist = cg.to_filelist()
        write_filelist(filelist, path="fromlis.lis")

        # Step: Output a control network
        to_isis('TestTwoImageMatching.net',
                cg,
                mode='wb',
                networkid='TestTwoImageMatching',
                targetname='Moon')