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_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_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 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'))
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)
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') 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_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_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 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')
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_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_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") 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_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 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'))
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 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')
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')