Loading autocnet/graph/network.py +4 −0 Original line number Diff line number Diff line Loading @@ -891,3 +891,7 @@ class CandidateGraph(nx.Graph): return False return True def footprints(self): geoms = [n.footprint for i, n in self.nodes_iter(data=True)] return gpd.GeoDataFrame(geometry=geoms) autocnet/graph/node.py +32 −7 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ from plio.io.io_gdal import GeoDataset from plio.io.isis_serial_number import generate_serial_number from scipy.misc import bytescale, imresize from shapely.geometry import Polygon from shapely import wkt from autocnet.cg import cg from autocnet.control.control import Correspondence, Point Loading Loading @@ -145,6 +146,16 @@ class Node(dict, MutableMapping): boolean_mask = v[1] self.masks[column_name] = boolean_mask """ @property def footprint(self): if not getattr(self, '_footprint', None): try: self._footprint = wkt.loads(self.geodata.footprint.GetGeometryRef(0).ExportToWkt()) except: return None return self._footprint @property def isis_serial(self): """ Loading Loading @@ -262,6 +273,15 @@ class Node(dict, MutableMapping): return keypoints def get_raw_keypoint_coordinates(self, index): """ The performance of get_keypoint_coordinates can be slow due to the ability for fancier indexing. This method returns coordinates using numpy array accessors. """ index = index.astype(np.int) return self.keypoints.values[index,:2] @staticmethod def _extract_features(array, *args, **kwargs): """ Loading Loading @@ -463,23 +483,28 @@ class Node(dict, MutableMapping): # Add the point object onto the node point = Point(pid) #print(g[['source_image', 'destination_image']]) covered_edges = list(map(tuple, g[['source_image', 'destination_image']].values)) s = g['source_image'].iat[0] d = g['destination_image'].iat[0] # The reference edge that we are deepening with ab = cg.edge[covered_edges[0][0]][covered_edges[0][1]] ab = cg.edge[s][d] # Get the coordinates of the search correspondence ab_keypoints = ab.source.get_keypoint_coordinates(index=g['source_idx']) ab_keypoints = ab.source.get_raw_keypoint_coordinates(index=g['source_idx']) ab_x = None for j, (r_idx, r) in enumerate(g.iterrows()): kp = ab_keypoints.iloc[j].values if len(g) == 1: kp = ab_keypoints else: kp = ab_keypoints[j] # Homogenize the coord used for epipolar projection if ab_x is None: ab_x = np.array([kp[0], kp[1], 1.]) kpd = ab.destination.get_keypoint_coordinates(index=g['destination_idx']).values[0] kpd = ab.destination.get_raw_keypoint_coordinates(index=g['destination_idx']) if len(kpd.shape) > 1: kpd = kpd[0] # Add the existing source and destination correspondences self.point_to_correspondence[point].add((r['source_image'], Correspondence(r['source_idx'], Loading autocnet/graph/tests/test_network.py +19 −5 Original line number Diff line number Diff line Loading @@ -5,13 +5,12 @@ import sys import pytest import unittest from unittest.mock import patch from unittest.mock import PropertyMock from osgeo import ogr from unittest.mock import MagicMock from plio.io import io_gdal from unittest.mock import patch, PropertyMock, MagicMock import geopandas as gpd import numpy as np from osgeo import ogr from plio.io import io_gdal from autocnet.examples import get_path Loading @@ -27,6 +26,17 @@ def graph(): return network.CandidateGraph.from_adjacency(get_path('three_image_adjacency.json'), basepath=basepath) @pytest.fixture() 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) @pytest.fixture() def disconnected_graph(): return network.CandidateGraph.from_adjacency(get_path('adjacency.json')) Loading Loading @@ -247,3 +257,7 @@ def test_is_complete(graph): assert False == incomplete_graph.is_complete() assert True == graph.is_complete() def test_footprints(geo_graph): # This is just testing the interface - should get a geodataframe back assert isinstance(geo_graph.footprints(), gpd.GeoDataFrame) autocnet/graph/tests/test_node.py +11 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import warnings import numpy as np import pandas as pd import pytest from shapely.geometry import Polygon from autocnet.examples import get_path Loading @@ -26,6 +27,11 @@ class TestNode(object): return node.Node(image_name='AS15-M-0295_SML', image_path=img) @pytest.fixture def geo_node(self): img = get_path('AS15-M-0297_crop.cub') return node.Node(image_name='AS15-M-0297_crop.cub', image_path=img) def test_get_handle(self, node): assert isinstance(node.geodata, GeoDataset) Loading Loading @@ -125,3 +131,8 @@ class TestNode(object): columns=['a', 'b']) matches, mask = node._clean(clean_keys=['a']) assert mask.equals(pd.Series([True, True, True, False, False])) def test_footprint(self, geo_node): # Esnure that a shapely compliant poly is being returned assert isinstance(geo_node.footprint, Polygon) Loading
autocnet/graph/network.py +4 −0 Original line number Diff line number Diff line Loading @@ -891,3 +891,7 @@ class CandidateGraph(nx.Graph): return False return True def footprints(self): geoms = [n.footprint for i, n in self.nodes_iter(data=True)] return gpd.GeoDataFrame(geometry=geoms)
autocnet/graph/node.py +32 −7 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ from plio.io.io_gdal import GeoDataset from plio.io.isis_serial_number import generate_serial_number from scipy.misc import bytescale, imresize from shapely.geometry import Polygon from shapely import wkt from autocnet.cg import cg from autocnet.control.control import Correspondence, Point Loading Loading @@ -145,6 +146,16 @@ class Node(dict, MutableMapping): boolean_mask = v[1] self.masks[column_name] = boolean_mask """ @property def footprint(self): if not getattr(self, '_footprint', None): try: self._footprint = wkt.loads(self.geodata.footprint.GetGeometryRef(0).ExportToWkt()) except: return None return self._footprint @property def isis_serial(self): """ Loading Loading @@ -262,6 +273,15 @@ class Node(dict, MutableMapping): return keypoints def get_raw_keypoint_coordinates(self, index): """ The performance of get_keypoint_coordinates can be slow due to the ability for fancier indexing. This method returns coordinates using numpy array accessors. """ index = index.astype(np.int) return self.keypoints.values[index,:2] @staticmethod def _extract_features(array, *args, **kwargs): """ Loading Loading @@ -463,23 +483,28 @@ class Node(dict, MutableMapping): # Add the point object onto the node point = Point(pid) #print(g[['source_image', 'destination_image']]) covered_edges = list(map(tuple, g[['source_image', 'destination_image']].values)) s = g['source_image'].iat[0] d = g['destination_image'].iat[0] # The reference edge that we are deepening with ab = cg.edge[covered_edges[0][0]][covered_edges[0][1]] ab = cg.edge[s][d] # Get the coordinates of the search correspondence ab_keypoints = ab.source.get_keypoint_coordinates(index=g['source_idx']) ab_keypoints = ab.source.get_raw_keypoint_coordinates(index=g['source_idx']) ab_x = None for j, (r_idx, r) in enumerate(g.iterrows()): kp = ab_keypoints.iloc[j].values if len(g) == 1: kp = ab_keypoints else: kp = ab_keypoints[j] # Homogenize the coord used for epipolar projection if ab_x is None: ab_x = np.array([kp[0], kp[1], 1.]) kpd = ab.destination.get_keypoint_coordinates(index=g['destination_idx']).values[0] kpd = ab.destination.get_raw_keypoint_coordinates(index=g['destination_idx']) if len(kpd.shape) > 1: kpd = kpd[0] # Add the existing source and destination correspondences self.point_to_correspondence[point].add((r['source_image'], Correspondence(r['source_idx'], Loading
autocnet/graph/tests/test_network.py +19 −5 Original line number Diff line number Diff line Loading @@ -5,13 +5,12 @@ import sys import pytest import unittest from unittest.mock import patch from unittest.mock import PropertyMock from osgeo import ogr from unittest.mock import MagicMock from plio.io import io_gdal from unittest.mock import patch, PropertyMock, MagicMock import geopandas as gpd import numpy as np from osgeo import ogr from plio.io import io_gdal from autocnet.examples import get_path Loading @@ -27,6 +26,17 @@ def graph(): return network.CandidateGraph.from_adjacency(get_path('three_image_adjacency.json'), basepath=basepath) @pytest.fixture() 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) @pytest.fixture() def disconnected_graph(): return network.CandidateGraph.from_adjacency(get_path('adjacency.json')) Loading Loading @@ -247,3 +257,7 @@ def test_is_complete(graph): assert False == incomplete_graph.is_complete() assert True == graph.is_complete() def test_footprints(geo_graph): # This is just testing the interface - should get a geodataframe back assert isinstance(geo_graph.footprints(), gpd.GeoDataFrame)
autocnet/graph/tests/test_node.py +11 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import warnings import numpy as np import pandas as pd import pytest from shapely.geometry import Polygon from autocnet.examples import get_path Loading @@ -26,6 +27,11 @@ class TestNode(object): return node.Node(image_name='AS15-M-0295_SML', image_path=img) @pytest.fixture def geo_node(self): img = get_path('AS15-M-0297_crop.cub') return node.Node(image_name='AS15-M-0297_crop.cub', image_path=img) def test_get_handle(self, node): assert isinstance(node.geodata, GeoDataset) Loading Loading @@ -125,3 +131,8 @@ class TestNode(object): columns=['a', 'b']) matches, mask = node._clean(clean_keys=['a']) assert mask.equals(pd.Series([True, True, True, False, False])) def test_footprint(self, geo_node): # Esnure that a shapely compliant poly is being returned assert isinstance(geo_node.footprint, Polygon)