Loading autocnet/cg/cg.py +56 −0 Original line number Diff line number Diff line import json import ogr import pandas as pd from scipy.spatial import ConvexHull Loading Loading @@ -45,3 +47,57 @@ def overlapping_polygon_area(polys): intersection = intersection.Intersection(geom) area = intersection.GetArea() return area def convex_hull(points): """ Parameters ---------- points : ndarray (n, 2) array of point coordinates Returns ------- hull : 2-D convex hull Provides a convex hull that is used to determine coverage """ if isinstance(points, pd.DataFrame) : points = pd.DataFrame.as_matrix(points) hull = ConvexHull(points) return hull def two_poly_overlap(poly1, poly2): """ Parameters ---------- poly1 : ogr polygon Any polygon that shares some kind of overlap with poly2 poly2 : ogr polygon Any polygon that shares some kind of overlap with poly1 Returns ------- overlap_info : list Percentage of overlap between the two images and the area that is being overlapped """ a_o = poly2.Intersection(poly1).GetArea() area1 = poly1.GetArea() area2 = poly2.GetArea() overlap_area = a_o overlap_percn = (a_o / (area1 + area2 - a_o)) * 100 overlap_info = [overlap_percn, overlap_area] return overlap_info autocnet/cg/tests/test_cg.py +13 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ sys.path.insert(0, os.path.abspath('..')) import numpy as np from .. import cg from osgeo import ogr class TestArea(unittest.TestCase): Loading @@ -19,3 +20,15 @@ class TestArea(unittest.TestCase): ratio = cg.convex_hull_ratio(self.pts, total_area) self.assertAlmostEqual(0.7566490, ratio, 5) def test_overlap(self): wkt1 = "POLYGON ((0 40, 40 40, 40 0, 0 0, 0 40))" wkt2 = "POLYGON ((20 60, 60 60, 60 20, 20 20, 20 60))" poly1 = ogr.CreateGeometryFromWkt(wkt1) poly2 = ogr.CreateGeometryFromWkt(wkt2) info = cg.two_poly_overlap(poly1, poly2) self.assertEqual(info[1], 400) self.assertAlmostEqual(info[0], 14.285714285) No newline at end of file autocnet/graph/edge.py +23 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ from autocnet.matcher import suppression_funcs as spf from autocnet.matcher import subpixel as sp from autocnet.transformation.transformations import FundamentalMatrix, Homography from autocnet.vis.graph_view import plot_edge from autocnet.cg import cg class Edge(dict, MutableMapping): Loading @@ -31,6 +32,11 @@ class Edge(dict, MutableMapping): With key equal to an autoincrementing integer and value equal to a dict of parameters used to generate this realization. weight : dict Dictionary with two keys overlap_area, and overlap_percn overlap_area returns the area overlaped by both images overlap_percn retuns the total percentage of overlap """ def __init__(self, source=None, destination=None): Loading @@ -41,6 +47,8 @@ class Edge(dict, MutableMapping): self.fundamental_matrix = None self._subpixel_offsets = None self.weight = {} self._observers = set() # Subscribe the heatlh observer Loading Loading @@ -410,3 +418,18 @@ class Edge(dict, MutableMapping): mask = pd.Series(True, self.matches.index) return matches, mask def overlap(self): """ Acts on an edge and returns the overlap area and percentage of overlap between the two images on the edge. Data is returned to the weight dictionary """ poly1 = self.source.geodata.footprint poly2 = self.destination.geodata.footprint overlapinfo = cg.two_poly_overlap(poly1, poly2) self.weight['overlap_area'] = overlapinfo[1] self.weight['overlap_percn'] = overlapinfo[0] autocnet/graph/network.py +10 −2 Original line number Diff line number Diff line Loading @@ -4,8 +4,6 @@ import warnings import dill as pickle import networkx as nx import numpy as np import pandas as pd from autocnet.control.control import CorrespondenceNetwork from autocnet.fileio import io_hdf Loading Loading @@ -476,6 +474,16 @@ class CandidateGraph(nx.Graph): ''' self.apply_func_to_edges('suppress', *args, **kwargs) def overlap(self): ''' Compute the percentage and area coverage of two images See Also -------- autocnet.cg.cg.two_image_overlap ''' self.apply_func_to_edges('overlap') def minimum_spanning_tree(self): """ Calculates the minimum spanning tree of the graph Loading autocnet/graph/node.py +29 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ import numpy as np import pandas as pd from scipy.misc import bytescale from autocnet.cg import cg from autocnet.fileio.io_gdal import GeoDataset from autocnet.fileio import io_hdf from autocnet.matcher import feature_extractor as fe Loading Loading @@ -114,6 +115,33 @@ class Node(dict, MutableMapping): self._isis_serial = None return self._isis_serial def coverage(self): """ Determines the area of keypoint coverage using the unprojected image, resulting in a rough estimation of the percentage area being covered. Returns ------- coverage_area : float Area covered by the generated keypoints """ points = self.get_keypoint_coordinates() hull = cg.convex_hull(points) hull_area = hull.volume max_x = self.geodata.raster_size[0] max_y = self.geodata.raster_size[1] total_area = max_x * max_y self.coverage_area = (hull_area/total_area)*100 return self.coverage_area def get_array(self, band=1): """ Get a band as a 32-bit numpy array Loading Loading @@ -343,3 +371,4 @@ class Node(dict, MutableMapping): mask = panel[clean_keys].all(axis=1) matches = self._keypoints[mask] return matches, mask Loading
autocnet/cg/cg.py +56 −0 Original line number Diff line number Diff line import json import ogr import pandas as pd from scipy.spatial import ConvexHull Loading Loading @@ -45,3 +47,57 @@ def overlapping_polygon_area(polys): intersection = intersection.Intersection(geom) area = intersection.GetArea() return area def convex_hull(points): """ Parameters ---------- points : ndarray (n, 2) array of point coordinates Returns ------- hull : 2-D convex hull Provides a convex hull that is used to determine coverage """ if isinstance(points, pd.DataFrame) : points = pd.DataFrame.as_matrix(points) hull = ConvexHull(points) return hull def two_poly_overlap(poly1, poly2): """ Parameters ---------- poly1 : ogr polygon Any polygon that shares some kind of overlap with poly2 poly2 : ogr polygon Any polygon that shares some kind of overlap with poly1 Returns ------- overlap_info : list Percentage of overlap between the two images and the area that is being overlapped """ a_o = poly2.Intersection(poly1).GetArea() area1 = poly1.GetArea() area2 = poly2.GetArea() overlap_area = a_o overlap_percn = (a_o / (area1 + area2 - a_o)) * 100 overlap_info = [overlap_percn, overlap_area] return overlap_info
autocnet/cg/tests/test_cg.py +13 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ sys.path.insert(0, os.path.abspath('..')) import numpy as np from .. import cg from osgeo import ogr class TestArea(unittest.TestCase): Loading @@ -19,3 +20,15 @@ class TestArea(unittest.TestCase): ratio = cg.convex_hull_ratio(self.pts, total_area) self.assertAlmostEqual(0.7566490, ratio, 5) def test_overlap(self): wkt1 = "POLYGON ((0 40, 40 40, 40 0, 0 0, 0 40))" wkt2 = "POLYGON ((20 60, 60 60, 60 20, 20 20, 20 60))" poly1 = ogr.CreateGeometryFromWkt(wkt1) poly2 = ogr.CreateGeometryFromWkt(wkt2) info = cg.two_poly_overlap(poly1, poly2) self.assertEqual(info[1], 400) self.assertAlmostEqual(info[0], 14.285714285) No newline at end of file
autocnet/graph/edge.py +23 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ from autocnet.matcher import suppression_funcs as spf from autocnet.matcher import subpixel as sp from autocnet.transformation.transformations import FundamentalMatrix, Homography from autocnet.vis.graph_view import plot_edge from autocnet.cg import cg class Edge(dict, MutableMapping): Loading @@ -31,6 +32,11 @@ class Edge(dict, MutableMapping): With key equal to an autoincrementing integer and value equal to a dict of parameters used to generate this realization. weight : dict Dictionary with two keys overlap_area, and overlap_percn overlap_area returns the area overlaped by both images overlap_percn retuns the total percentage of overlap """ def __init__(self, source=None, destination=None): Loading @@ -41,6 +47,8 @@ class Edge(dict, MutableMapping): self.fundamental_matrix = None self._subpixel_offsets = None self.weight = {} self._observers = set() # Subscribe the heatlh observer Loading Loading @@ -410,3 +418,18 @@ class Edge(dict, MutableMapping): mask = pd.Series(True, self.matches.index) return matches, mask def overlap(self): """ Acts on an edge and returns the overlap area and percentage of overlap between the two images on the edge. Data is returned to the weight dictionary """ poly1 = self.source.geodata.footprint poly2 = self.destination.geodata.footprint overlapinfo = cg.two_poly_overlap(poly1, poly2) self.weight['overlap_area'] = overlapinfo[1] self.weight['overlap_percn'] = overlapinfo[0]
autocnet/graph/network.py +10 −2 Original line number Diff line number Diff line Loading @@ -4,8 +4,6 @@ import warnings import dill as pickle import networkx as nx import numpy as np import pandas as pd from autocnet.control.control import CorrespondenceNetwork from autocnet.fileio import io_hdf Loading Loading @@ -476,6 +474,16 @@ class CandidateGraph(nx.Graph): ''' self.apply_func_to_edges('suppress', *args, **kwargs) def overlap(self): ''' Compute the percentage and area coverage of two images See Also -------- autocnet.cg.cg.two_image_overlap ''' self.apply_func_to_edges('overlap') def minimum_spanning_tree(self): """ Calculates the minimum spanning tree of the graph Loading
autocnet/graph/node.py +29 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ import numpy as np import pandas as pd from scipy.misc import bytescale from autocnet.cg import cg from autocnet.fileio.io_gdal import GeoDataset from autocnet.fileio import io_hdf from autocnet.matcher import feature_extractor as fe Loading Loading @@ -114,6 +115,33 @@ class Node(dict, MutableMapping): self._isis_serial = None return self._isis_serial def coverage(self): """ Determines the area of keypoint coverage using the unprojected image, resulting in a rough estimation of the percentage area being covered. Returns ------- coverage_area : float Area covered by the generated keypoints """ points = self.get_keypoint_coordinates() hull = cg.convex_hull(points) hull_area = hull.volume max_x = self.geodata.raster_size[0] max_y = self.geodata.raster_size[1] total_area = max_x * max_y self.coverage_area = (hull_area/total_area)*100 return self.coverage_area def get_array(self, band=1): """ Get a band as a 32-bit numpy array Loading Loading @@ -343,3 +371,4 @@ class Node(dict, MutableMapping): mask = panel[clean_keys].all(axis=1) matches = self._keypoints[mask] return matches, mask