Loading autocnet/graph/edge.py +21 −6 Original line number Diff line number Diff line from collections import MutableMapping import warnings from collections import MutableMapping import numpy as np import pandas as pd from pysal.cg.shapes import Polygon from autocnet.matcher import subpixel as sp from autocnet.matcher.transformations import FundamentalMatrix, Homography from autocnet.cg.cg import convex_hull_ratio from autocnet.cg.cg import overlapping_polygon_area from autocnet.vis.graph_view import plot_edge from autocnet.matcher import health from autocnet.matcher import outlier_detector as od from autocnet.cg.cg import convex_hull_ratio from autocnet.matcher import subpixel as sp from autocnet.transformation.transformations import FundamentalMatrix, Homography from autocnet.vis.graph_view import plot_edge class Edge(dict, MutableMapping): Loading @@ -35,9 +36,15 @@ class Edge(dict, MutableMapping): self.source = source self.destination = destination self._homography = None self.homography = None self.fundamental_matrix = None self._subpixel_offsets = None self._observers = set() #Subscribe the heatlh observer self._health = health.EdgeHealth() def __repr__(self): return """ Source Image Index: {} Loading Loading @@ -67,6 +74,10 @@ class Edge(dict, MutableMapping): boolean_mask = v[1] self.masks[column_name] = boolean_mask @property def health(self): return self._health.health def keypoints(self, clean_keys=[]): """ Return a view of the keypoints dataframe after having applied some Loading Loading @@ -137,6 +148,10 @@ class Edge(dict, MutableMapping): all_destin_keypoints[['x', 'y']], mask=mask) # Subscribe the health watcher to the fundamental matrix observable self.fundamental_matrix.subscribe(self._health.update) self.fundamental_matrix._notify_subscribers(self.fundamental_matrix) # Set the initial state of the fundamental mask in the masks self.masks = ('fundamental', mask) Loading autocnet/graph/network.py +8 −6 Original line number Diff line number Diff line Loading @@ -175,7 +175,6 @@ class CandidateGraph(nx.Graph): raise NotImplementedError self.add_node(self.node_counter, *args, **kwargs) #self.node_labels[self.node[self.node_counter]['image_name']] = self.node_counter self.node_counter += 1 def extract_features(self, method='orb', extractor_parameters={}): Loading Loading @@ -225,7 +224,7 @@ class CandidateGraph(nx.Graph): def add_matches(self, matches): """ Adds match data to a node and attributes the data to the appropriate edges, e.g. if A-B have a match, edge A-B is attributes appropriate edges, e.g. if A-B have a match, edge A-B is attributed with the pandas dataframe. Parameters Loading @@ -233,13 +232,16 @@ class CandidateGraph(nx.Graph): matches : dataframe The pandas dataframe containing the matches """ edges = self.edges() source_groups = matches.groupby('source_image') for i, source_group in source_groups: for j, dest_group in source_group.groupby('destination_image'): source_key = dest_group['source_image'].values[0] destination_key = dest_group['destination_image'].values[0] if (source_key, destination_key) in edges: edge = self.edge[source_key][destination_key] else: edge = self.edge[destination_key][source_key] if hasattr(edge, 'matches'): df = edge.matches Loading autocnet/matcher/health.py 0 → 100644 +29 −0 Original line number Diff line number Diff line class EdgeHealth(object): """ Storage and computation of the health of a graph edge using the metric: """ def __init__(self): self.FundamentalMatrix = 0.0 @property def health(self): return self.recompute_health() def update(self, *args, **kwargs): """ Pass through called when the observable (model) changes. *args and **kwargs are passed through from the observable. """ for a in args: if hasattr(self, a.__class__.__name__): setattr(self, a.__class__.__name__, a) def recompute_health(self): """ Recompute the health of the edge. """ return self.FundamentalMatrix.error.mean() No newline at end of file autocnet/matcher/outlier_detector.py +5 −1 Original line number Diff line number Diff line Loading @@ -155,12 +155,16 @@ def compute_fundamental_matrix(kp1, kp2, method='ransac', reproj_threshold=5.0, else: raise ValueError("Unknown outlier detection method. Choices are: 'ransac', 'lmeds', or 'normal'.") transformation_matrix, mask = cv2.findFundamentalMat(kp1, kp2, method_, reproj_threshold, confidence) try: mask = mask.astype(bool) except: pass # pragma: no cover return transformation_matrix, mask Loading autocnet/transformation/__init__.py 0 → 100644 +0 −0 Empty file added. Loading
autocnet/graph/edge.py +21 −6 Original line number Diff line number Diff line from collections import MutableMapping import warnings from collections import MutableMapping import numpy as np import pandas as pd from pysal.cg.shapes import Polygon from autocnet.matcher import subpixel as sp from autocnet.matcher.transformations import FundamentalMatrix, Homography from autocnet.cg.cg import convex_hull_ratio from autocnet.cg.cg import overlapping_polygon_area from autocnet.vis.graph_view import plot_edge from autocnet.matcher import health from autocnet.matcher import outlier_detector as od from autocnet.cg.cg import convex_hull_ratio from autocnet.matcher import subpixel as sp from autocnet.transformation.transformations import FundamentalMatrix, Homography from autocnet.vis.graph_view import plot_edge class Edge(dict, MutableMapping): Loading @@ -35,9 +36,15 @@ class Edge(dict, MutableMapping): self.source = source self.destination = destination self._homography = None self.homography = None self.fundamental_matrix = None self._subpixel_offsets = None self._observers = set() #Subscribe the heatlh observer self._health = health.EdgeHealth() def __repr__(self): return """ Source Image Index: {} Loading Loading @@ -67,6 +74,10 @@ class Edge(dict, MutableMapping): boolean_mask = v[1] self.masks[column_name] = boolean_mask @property def health(self): return self._health.health def keypoints(self, clean_keys=[]): """ Return a view of the keypoints dataframe after having applied some Loading Loading @@ -137,6 +148,10 @@ class Edge(dict, MutableMapping): all_destin_keypoints[['x', 'y']], mask=mask) # Subscribe the health watcher to the fundamental matrix observable self.fundamental_matrix.subscribe(self._health.update) self.fundamental_matrix._notify_subscribers(self.fundamental_matrix) # Set the initial state of the fundamental mask in the masks self.masks = ('fundamental', mask) Loading
autocnet/graph/network.py +8 −6 Original line number Diff line number Diff line Loading @@ -175,7 +175,6 @@ class CandidateGraph(nx.Graph): raise NotImplementedError self.add_node(self.node_counter, *args, **kwargs) #self.node_labels[self.node[self.node_counter]['image_name']] = self.node_counter self.node_counter += 1 def extract_features(self, method='orb', extractor_parameters={}): Loading Loading @@ -225,7 +224,7 @@ class CandidateGraph(nx.Graph): def add_matches(self, matches): """ Adds match data to a node and attributes the data to the appropriate edges, e.g. if A-B have a match, edge A-B is attributes appropriate edges, e.g. if A-B have a match, edge A-B is attributed with the pandas dataframe. Parameters Loading @@ -233,13 +232,16 @@ class CandidateGraph(nx.Graph): matches : dataframe The pandas dataframe containing the matches """ edges = self.edges() source_groups = matches.groupby('source_image') for i, source_group in source_groups: for j, dest_group in source_group.groupby('destination_image'): source_key = dest_group['source_image'].values[0] destination_key = dest_group['destination_image'].values[0] if (source_key, destination_key) in edges: edge = self.edge[source_key][destination_key] else: edge = self.edge[destination_key][source_key] if hasattr(edge, 'matches'): df = edge.matches Loading
autocnet/matcher/health.py 0 → 100644 +29 −0 Original line number Diff line number Diff line class EdgeHealth(object): """ Storage and computation of the health of a graph edge using the metric: """ def __init__(self): self.FundamentalMatrix = 0.0 @property def health(self): return self.recompute_health() def update(self, *args, **kwargs): """ Pass through called when the observable (model) changes. *args and **kwargs are passed through from the observable. """ for a in args: if hasattr(self, a.__class__.__name__): setattr(self, a.__class__.__name__, a) def recompute_health(self): """ Recompute the health of the edge. """ return self.FundamentalMatrix.error.mean() No newline at end of file
autocnet/matcher/outlier_detector.py +5 −1 Original line number Diff line number Diff line Loading @@ -155,12 +155,16 @@ def compute_fundamental_matrix(kp1, kp2, method='ransac', reproj_threshold=5.0, else: raise ValueError("Unknown outlier detection method. Choices are: 'ransac', 'lmeds', or 'normal'.") transformation_matrix, mask = cv2.findFundamentalMat(kp1, kp2, method_, reproj_threshold, confidence) try: mask = mask.astype(bool) except: pass # pragma: no cover return transformation_matrix, mask Loading