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')
def test_fromlist(): mock_list = [ 'AS15-M-0295_SML.png', 'AS15-M-0296_SML.png', 'AS15-M-0297_SML.png', 'AS15-M-0298_SML.png', 'AS15-M-0299_SML.png', 'AS15-M-0300_SML.png' ] good_poly = ogr.CreateGeometryFromWkt( 'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))') bad_poly = ogr.CreateGeometryFromWkt( 'POLYGON ((9999 10, 40 40, 20 40, 10 20, 30 10))') with patch('plio.io.io_gdal.GeoDataset.footprint', new_callable=PropertyMock) as patch_fp: patch_fp.return_value = good_poly n = network.CandidateGraph.from_filelist(mock_list, get_path('Apollo15')) assert n.number_of_nodes() == 6 assert n.number_of_edges() == 15 patch_fp.return_value = bad_poly n = network.CandidateGraph.from_filelist(mock_list, get_path('Apollo15')) assert n.number_of_nodes() == 6 assert n.number_of_edges() == 0 n = network.CandidateGraph.from_filelist(mock_list, get_path('Apollo15')) assert len(n.nodes()) == 6 n = network.CandidateGraph.from_filelist(get_path('adjacency.lis'), get_path('Apollo15')) assert len(n.nodes()) == 6
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'])
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')
def setUp(self): im1 = cv2.imread(get_path('AS15-M-0296_SML.png')) im2 = cv2.imread(get_path('AS15-M-0297_SML.png')) self.fd = {} sift = cv2.xfeatures2d.SIFT_create(10) self.fd['AS15-M-0296_SML.png'] = sift.detectAndCompute(im1, None) self.fd['AS15-M-0297_SML.png'] = sift.detectAndCompute(im2, None)
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)
def setUpClass(cls): img = imread(get_path('AS15-M-0298_SML.png'), flatten=True) img_coord = (482.09783936, 652.40679932) cls.template = sp.clip_roi(img, img_coord, 5) cls.template = rotate(cls.template, 90) cls.template = imresize(cls.template, 1.) cls.search = sp.clip_roi(img, img_coord, 21) cls.search = rotate(cls.search, 0) cls.search = imresize(cls.search, 1.) cls.offset = (1, 1) cls.offset_template = sp.clip_roi(img, np.add(img_coord, cls.offset), 5) cls.offset_template = rotate(cls.offset_template, 0) cls.offset_template = imresize(cls.offset_template, 1.) cls.search_center = [math.floor(cls.search.shape[0]/2), math.floor(cls.search.shape[1]/2)] cls.upsampling = 10 cls.alpha = math.pi/2 cls.cifi_thresh = 90 cls.rafi_thresh = 90 cls.tefi_thresh = 100 cls.use_percentile = True cls.radii = list(range(1, 3)) cls.cifi_number_of_warnings = 2 cls.rafi_number_of_warnings = 2
def geo_graph(): basepath = get_path('Apollo15') a = 'AS15-M-0297_crop.cub' b = 'AS15-M-0298_crop.cub' c = 'AS15-M-0299_crop.cub' adjacency = {a: [b, c], b: [a, c], c: [a, b]} return network.CandidateGraph.from_adjacency(adjacency, basepath=basepath)
def test_add_node(): basepath = get_path('Apollo15') a = 'AS15-M-0297_crop.cub' b = 'AS15-M-0298_crop.cub' c = 'AS15-M-0299_crop.cub' adjacency = {a: [b], b: [a]} g = network.CandidateGraph.from_adjacency(adjacency, basepath=basepath) # Test without "image_name" arg (networkx parent method) g.add_node(2, data=node.Node(image_name=c, image_path=os.path.join(basepath, c), node_id=2)) assert len(g.nodes) == 3 assert g.node[2]["data"]["image_name"] == c # Test with "image_name" (cg method) g = network.CandidateGraph.from_adjacency(adjacency, basepath=basepath) g.add_node(image_name=c, basepath=basepath) assert len(g.nodes) == 3 assert g.node[2]["data"]["image_name"] == c assert g.node[0].keys() == g.node[1].keys() == g.node[2].keys() # Test when "image_name" not found node_len = len(g.nodes) g.add_node(image_name="nonexistent.jpg") assert len(g.nodes) == node_len
def setUpClass(cls): img = imread(get_path('AS15-M-0298_SML.png'), flatten=True) img_coord = (482.09783936, 652.40679932) cls.template = sp.clip_roi(img, img_coord, 5) cls.template = rotate(cls.template, 90) cls.template = imresize(cls.template, 1.) cls.search = sp.clip_roi(img, img_coord, 21) cls.search = rotate(cls.search, 0) cls.search = imresize(cls.search, 1.) cls.offset = (1, 1) cls.offset_template = sp.clip_roi(img, np.add(img_coord, cls.offset), 5) cls.offset_template = rotate(cls.offset_template, 0) cls.offset_template = imresize(cls.offset_template, 1.) cls.search_center = [ math.floor(cls.search.shape[0] / 2), math.floor(cls.search.shape[1] / 2) ] cls.upsampling = 10 cls.alpha = math.pi / 2 cls.cifi_thresh = 90 cls.rafi_thresh = 90 cls.tefi_thresh = 100 cls.use_percentile = True cls.radii = list(range(1, 3)) cls.cifi_number_of_warnings = 2 cls.rafi_number_of_warnings = 2
def setUp(self): self.dataset = io_gdal.GeoDataset(get_path('Mars_MGS_MOLA_ClrShade_MAP2_0.0N0.0_MERC.tif')) self.data_array = self.dataset.read_array() self.parameters = {"nfeatures" : 10, "nOctaveLayers" : 3, "contrastThreshold" : 0.02, "edgeThreshold" : 10, "sigma" : 1.6}
def setUpClass(cls): cls.dataset = io_gdal.GeoDataset(get_path('AS15-M-0295_SML.png')) cls.data_array = cls.dataset.read_array(dtype='uint8') cls.parameters = {"nfeatures": 10, "nOctaveLayers": 3, "contrastThreshold": 0.02, "edgeThreshold": 10, "sigma": 1.6}
def test_add_node_by_name(reduced_geo): # Test with "image_name" (cg method) c = 'AS15-M-0299_crop.cub' basepath = get_path('Apollo15') reduced_geo.add_node(image_name=c, basepath=basepath) assert len(reduced_geo.nodes) == 3 assert reduced_geo.node[2]["data"]["image_name"] == c assert reduced_geo.node[0].keys() == reduced_geo.node[1].keys() == reduced_geo.node[2].keys()
def geo_graph(): basepath = get_path('Apollo15') a = 'AS15-M-0297_crop.cub' b = 'AS15-M-0298_crop.cub' c = 'AS15-M-0299_crop.cub' adjacency = {a:[b,c], b:[a,c], c:[a,b]} return network.CandidateGraph.from_adjacency(adjacency, basepath=basepath)
def test_add_node(reduced_geo): # Test without "image_name" arg (networkx parent method) c = 'AS15-M-0299_crop.cub' basepath = get_path('Apollo15') reduced_geo.add_node(2, data=node.Node(image_name=c, image_path=os.path.join(basepath, c), node_id=2)) assert len(reduced_geo.nodes) == 3 assert reduced_geo.node[2]["data"]["image_name"] == c
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)
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 setUpClass(cls): cls.dataset = io_gdal.GeoDataset(get_path('AS15-M-0295_SML.png')) cls.data_array = cls.dataset.read_array(dtype='uint8') cls.parameters = { "nfeatures": 10, "nOctaveLayers": 3, "contrastThreshold": 0.02, "edgeThreshold": 10, "sigma": 1.6 }
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')
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')
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')
def setUpClass(self): # actually set up everything for matches im1 = cv2.imread(get_path('AS15-M-0296_SML.png')) im2 = cv2.imread(get_path('AS15-M-0297_SML.png')) fd = {} sift = cv2.xfeatures2d.SIFT_create(10) fd['AS15-M-0296_SML.png'] = sift.detectAndCompute(im1, None) fd['AS15-M-0297_SML.png'] = sift.detectAndCompute(im2, None) fmatcher = matcher.FlannMatcher() truth_image_indices = {} counter = 0 for imageid, (keypoint, descriptor) in fd.items(): truth_image_indices[counter] = imageid fmatcher.add(descriptor, imageid) counter += 1 fmatcher.train() self.matches = fmatcher.query(fd['AS15-M-0296_SML.png'][1], 'AS15-M-0296_SML.png')
def setUpClass(self): # actually set up everything for matches im1 = cv2.imread(get_path('AS15-M-0296_SML.png')) im2 = cv2.imread(get_path('AS15-M-0297_SML.png')) fd = {} sift = cv2.xfeatures2d.SIFT_create(10) fd['AS15-M-0296_SML.png'] = sift.detectAndCompute(im1, None) fd['AS15-M-0297_SML.png'] = sift.detectAndCompute(im2, None) fmatcher = matcher.FlannMatcher() truth_image_indices = {} counter = 0 for imageid, (keypoint, descriptor) in fd.items(): truth_image_indices[counter] = imageid fmatcher.add(descriptor, imageid) counter += 1 fmatcher.train() self.matches = fmatcher.query(fd['AS15-M-0296_SML.png'][1],'AS15-M-0296_SML.png', k=3)
def test_from_adjacency(): basepath = get_path('Apollo15') a = 'AS15-M-0297_crop.cub' b = 'AS15-M-0298_crop.cub' c = 'AS15-M-0299_crop.cub' adjacency = {a: [b, c], b: [a, c], c: [a, b]} g = network.CandidateGraph.from_adjacency(adjacency, basepath=basepath) assert len(g.nodes) == 3 assert len(g.edges) == 3 for s, d, e in g.edges.data('data'): assert isinstance(e, edge.Edge) assert isinstance(g.nodes[s]['data'], node.Node)
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")
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')
def test_fromlist(self): mock_list = ['AS15-M-0295_SML.png', 'AS15-M-0296_SML.png', 'AS15-M-0297_SML.png', 'AS15-M-0298_SML.png', 'AS15-M-0299_SML.png', 'AS15-M-0300_SML.png'] good_poly = ogr.CreateGeometryFromWkt('POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))') bad_poly = ogr.CreateGeometryFromWkt('POLYGON ((9999 10, 40 40, 20 40, 10 20, 30 10))') with patch('autocnet.fileio.io_gdal.GeoDataset.footprint', new_callable=PropertyMock) as patch_fp: patch_fp.return_value = good_poly n = network.CandidateGraph.from_filelist(mock_list, get_path('Apollo15')) self.assertEqual(n.number_of_nodes(), 6) self.assertEqual(n.number_of_edges(), 15) patch_fp.return_value = bad_poly n = network.CandidateGraph.from_filelist(mock_list, get_path('Apollo15')) self.assertEqual(n.number_of_nodes(), 6) self.assertEqual(n.number_of_edges(), 0) n = network.CandidateGraph.from_filelist(mock_list, get_path('Apollo15')) self.assertEqual(len(n.nodes()), 6) n = network.CandidateGraph.from_filelist(get_path('adjacency.lis'), get_path('Apollo15')) self.assertEqual(len(n.nodes()), 6)
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'])
def test_from_adjacency(): basepath = get_path('Apollo15') a = 'AS15-M-0297_crop.cub' b = 'AS15-M-0298_crop.cub' c = 'AS15-M-0299_crop.cub' adjacency = {a:[b,c], b:[a,c], c:[a,b]} g = network.CandidateGraph.from_adjacency(adjacency, basepath=basepath) assert len(g.nodes) == 3 assert len(g.edges) == 3 for s, d, e in g.edges.data('data'): assert isinstance(e, edge.Edge) assert isinstance(g.nodes[s]['data'], node.Node)
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")
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')
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')
def test_add_edge(): basepath = get_path('Apollo15') a = 'AS15-M-0297_crop.cub' b = 'AS15-M-0298_crop.cub' c = 'AS15-M-0299_crop.cub' adjacency = {a:[b], b:[a]} c_adj = ['AS15-M-0297_crop.cub', 'AS15-M-0298_crop.cub'] g = network.CandidateGraph.from_adjacency(adjacency, basepath=basepath) g.add_node(image_name=c, basepath=basepath, adjacency=c_adj) assert len(g.edges) == 3 assert g.edges[0, 1]["data"].source == g.node[0]["data"] assert g.edges[0, 1]["data"].destination == g.node[1]["data"] assert g.edges[0, 2]["data"].source == g.node[0]["data"] assert g.edges[0, 2]["data"].destination == g.node[2]["data"] assert g.edges[1, 2]["data"].source == g.node[1]["data"] assert g.edges[1, 2]["data"].destination == g.node[2]["data"] assert g.edges[0, 1].keys() == g.edges[0, 2].keys() == g.edges[1, 2].keys()
def plotFeatures(imageName, keypoints, pointColorAndHatch='b.', featurePointSize=7): """ Plot an image and its found features using the image file name and a keypoint list found using autocnet.feature_extractor. The user may also specify the color and style of the points to be plotted and the size of the points. Parameters ---------- imageName : str The base name of the image file (without path). This will be the title of the plot. keypoints : list The keypoints of this image found by the feature extractor. pointColorAndHatch : str The color and hatch (symbol) to be used to mark the found features. Defaults to 'b.', blue and square dot. See matplotlib documentation for more choices. featurePointSize : int The size of the point marker. Defaults to 7. """ imgArray = GeoDataset(get_path(imageName)).read_array() height, width = imgArray.shape[:2] displayBox = np.zeros((height, width), np.uint8) displayBox[:height, :width] = imgArray plt.title(imageName) plt.margins(tight=True) plt.axis('off') plt.imshow(displayBox, cmap='Greys') for kp in keypoints: x,y = kp.pt plt.plot(x,y,pointColorAndHatch, markersize=featurePointSize)
def test_add_edge(): basepath = get_path('Apollo15') a = 'AS15-M-0297_crop.cub' b = 'AS15-M-0298_crop.cub' c = 'AS15-M-0299_crop.cub' adjacency = {a: [b], b: [a]} c_adj = ['AS15-M-0297_crop.cub', 'AS15-M-0298_crop.cub'] g = network.CandidateGraph.from_adjacency(adjacency, basepath=basepath) g.add_node(image_name=c, basepath=basepath, adjacency=c_adj) assert len(g.edges) == 3 assert g.edges[0, 1]["data"].source == g.node[0]["data"] assert g.edges[0, 1]["data"].destination == g.node[1]["data"] assert g.edges[0, 2]["data"].source == g.node[0]["data"] assert g.edges[0, 2]["data"].destination == g.node[2]["data"] assert g.edges[1, 2]["data"].source == g.node[1]["data"] assert g.edges[1, 2]["data"].destination == g.node[2]["data"] assert g.edges[0, 1].keys() == g.edges[0, 2].keys() == g.edges[1, 2].keys() # Test when adj img not found g = network.CandidateGraph.from_adjacency(adjacency, basepath=basepath) edge_len = len(g.edges) g.add_node(image_name=c, basepath=basepath, adjacency=["nonexistent.jpg"]) assert len(g.edges) == edge_len
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 plotAdjacencyGraphMatchesSingleDisplay(imageName1, imageName2, graph, featurePointSize=10, lineWidth=3): """ This is an earlier version of plotAdjacencyGraphMatches() where the images are offset in a single display box rather than in their own subplots. Parameters ---------- imageName : str The name of the first image file (with extension, without path). This will be the title of the left subplot. imageName : str The name of the second image file (with extension, without path). This will be the title of the right subplot. graph : object A CandicateGraph object containing the given images (as nodes) and their matches (edges). This graph is read from a JSON file, autocnet.feature_extractor has been applied, and FlannMatcher has been applied. featurePointSize : int The size of the feature point marker. Defaults to 10. lineWidth : int The width of the match lines. Defaults to 3. Returns ------- : AxesImage object An image object that can be saved. """ imgArray1 = GeoDataset(get_path(imageName1)).read_array() imgArray2 = GeoDataset(get_path(imageName2)).read_array() height1, width1 = imgArray1.shape[:2] height2, width2 = imgArray2.shape[:2] w = width1 + width2 + 50 h = max(height1, height2) displayBox = np.zeros((h, w), np.uint8) displayBox[:height1, :width1] = imgArray1 displayBox[:height2, width1 + 50:w] = imgArray2 for kp in graph.get_keypoints(imageName1): x, y = kp.pt plt.plot(x, y, 'ro', markersize=featurePointSize) for kp in graph.get_keypoints(imageName2): x, y = kp.pt plt.plot(x + width1 + 50, y, 'ro', markersize=featurePointSize) edge = graph[graph.node_name_map[imageName1]][ graph.node_name_map[imageName2]] if 'matches' in edge.keys(): for i, row in edge['matches'].iterrows(): # get matching points image1ID = int(row['source_idx']) image2ID = int(row['destination_idx']) keypointImage1 = (graph.get_keypoints(imageName1)[image1ID].pt[0], graph.get_keypoints(imageName1)[image1ID].pt[1]) keypointImage2 = (graph.get_keypoints(imageName2)[image2ID].pt[0] + width1 + 50, graph.get_keypoints(imageName2)[image2ID].pt[1]) # construct a line between the matching points using the data coordinates and the # transformation from data coordinates to display coordinates plt.plot([keypointImage1[0], keypointImage2[0]], [keypointImage1[1], keypointImage2[1]], color='g', marker='o', markeredgecolor='g', markersize=featurePointSize, linewidth=lineWidth, alpha=0.5) return plt.imshow(displayBox, cmap='Greys')
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)
def setUp(self): self.dataset = io_gdal.GeoDataset(get_path('Lunar_LRO_LOLA_Shade_MAP2_90.0N20.0_LAMB.tif'))
def setUp(self): self.examplefile = get_path('SP_2C_02_02358_S138_E3586.spc')
def setUp(self): self.g = CandidateGraph.from_graph(get_path('sixty_four_apollo.graph'))
def disconnected_graph(): return network.CandidateGraph.from_adjacency(get_path('adjacency.json'))
def test_read(self): d = io_json.read_json(get_path('logging.json')) self.assertIn('handlers', d.keys())
def img(): return imread(get_path('AS15-M-0298_SML.png'), flatten=True)
def graph(): basepath = get_path('Apollo15') return network.CandidateGraph.from_adjacency( get_path('three_image_adjacency.json'), basepath=basepath)
def setUp(self): self.dataset = io_gdal.GeoDataset( get_path('Mars_MGS_MOLA_ClrShade_MAP2_90.0N0.0_POLA.tif'))
def setUp(self): self.dataset = io_gdal.GeoDataset( get_path('Lunar_LRO_LOLA_Shade_MAP2_90.0N20.0_LAMB.tif'))
def test_read(self): d = io_yaml.read_yaml(get_path('logging.yaml')) self.assertIn('handlers', d.keys())
def apollo_subsets(): arr1 = imread(get_path('AS15-M-0295_SML(1).png'))[100:200, 123:223] arr2 = imread(get_path('AS15-M-0295_SML(2).png'))[235:335, 95:195] return arr1, arr2
def setUp(self): self.ds = io_gdal.GeoDataSet(get_path('Mars_MGS_MOLA_ClrShade_MAP2_90.0N0.0_POLA.tif'))
def setUp(self): self.g = load(get_path('sixty_four_apollo.proj'))
def test_generate_serial_number(self): label = get_path('Test_PVL.lbl') serial = isis_serial_numbers.generate_serial_number(label) self.assertEqual('APOLLO15/METRIC/1971-07-31T14:02:27.179', serial)
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')
def setUp(self): self.graph = network.CandidateGraph.from_adjacency(get_path('adjacency.json'))
def setUp(self): self.dataset = io_gdal.GeoDataset(get_path('Mars_MGS_MOLA_ClrShade_MAP2_0.0N0.0_MERC.tif'))
def apollo_subsets(): # These need to be geodata sets or just use mocks... arr1 = imread(get_path('AS15-M-0295_SML(1).png'))[100:201, 123:224] arr2 = imread(get_path('AS15-M-0295_SML(2).png'))[235:336, 95:196] return arr1, arr2
def setUp(self): img = get_path('AS15-M-0295_SML.png') self.node = node.Node(image_name='AS15-M-0295_SML', image_path=img)
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')