Loading .travis.yml +3 −1 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ python: - "3.5" before_install: install: # We do this conditionally because it saves us some downloading if the # version is the same. Loading @@ -26,11 +27,12 @@ install: - conda info -a # Create a virtual env and install dependencies - conda create -y -q -n test-env python=$TRAVIS_PYTHON_VERSION nose gdal numpy scipy pandas - conda create -y -q -n test-env python=$TRAVIS_PYTHON_VERSION nose gdal numpy pillow scipy pandas networkx # Activate the env - source activate test-env # Install the non-conda packages if required, requirements.txt duplicates are ignored - conda install -c https://conda.binstar.org/menpo opencv3 - conda install -c osgeo proj4 - pip install -r requirements.txt - pip install coverage Loading autocnet/control/control.py +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ from time import gmtime, strftime import pandas as pd POINT_TYPE = 2 MEASURE_TYPE = 2 class CSeries(pd.Series): """ Loading autocnet/fileio/io_gdal.py +1 −0 Original line number Diff line number Diff line Loading @@ -350,6 +350,7 @@ class GeoDataset(object): xextent, yextent).astype(dtype) return array def array_to_raster(array, file_name, projection=None, geotransform=None, outformat='GTiff', ndv=None): Loading autocnet/fileio/tests/io_controlnetwork.pydeleted 100644 → 0 +0 −0 Empty file deleted. autocnet/graph/network.py +97 −7 Original line number Diff line number Diff line from collections import Hashable from networkx import DiGraph import networkx as nx import pandas as pd from autocnet.control.control import C, POINT_TYPE, MEASURE_TYPE from autocnet.fileio import io_json class CandidateGraph(DiGraph): class CandidateGraph(nx.Graph): """ A NetworkX derived directed graph to store candidate overlap images. Loading @@ -12,8 +18,6 @@ class CandidateGraph(DiGraph): Attributes ---------- """ #TODO: This would be better with composition, and then dispatch the # network X calls to the graph object. def __init__(self,*args, **kwargs): super(CandidateGraph, self).__init__(*args, **kwargs) Loading @@ -36,6 +40,7 @@ class CandidateGraph(DiGraph): Parameters ========== outputfile : str PATH where the JSON will be written """ Loading @@ -44,18 +49,103 @@ class CandidateGraph(DiGraph): adjacency_dict[n] = self.neighbors(n) io_json.write_json(adjacency_dict, outputfile) def add_matches(self, source_node, 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 with the pandas dataframe. Parameters ---------- source_node : str The identifier for the node matches : dataframe The pandas dataframe containing the matches """ #TODO: This really belongs in an outlier detection matcher class, not here. # Remove erroneous self neighbors matches = matches.loc[matches['matched_to'] != source_node] groups = matches.groupby('matched_to') for destination_node, group in groups: try: edge = self[source_node][destination_node] except: edge = self[destination_node][source_node] if 'matches' in edge.keys(): df = edge['matches'] edge['matches'] = pd.merge(df, matches, left_on='queryIdx', right_on='trainIdx') else: edge['matches'] = matches def to_cnet(self): """ Returns ------- cnet : C A control network object """ data = [] point_ids = [] serials = [] for source, destination, attributes in self.edges_iter(data=True): for i, row in attributes['matches'].iterrows(): # Get the source and destination x,y coordinates for matches source_idx = row['queryIdx_x'] source_keypoints = (self.node[source]['keypoints'][source_idx].pt[0], self.node[source]['keypoints'][source_idx].pt[1]) destination_idx = row['queryIdx_y'] destination_keypoints = (self.node[destination]['keypoints'][destination_idx].pt[0], self.node[destination]['keypoints'][destination_idx].pt[1]) data.append(source_keypoints) data.append(destination_keypoints) serials.append(source) serials.append(destination) point_ids.append(i) point_ids.append(i) point_types = [2] * len(point_ids) measure_types = [2] * len(point_ids) multi_index = pd.MultiIndex.from_tuples(list(zip(point_ids,point_types, serials, measure_types))) columns = ['x', 'y'] cnet = C(data, index=multi_index, columns=columns) # TODO: This method assumes a 2 image match and should be generalized to build an n-image C object return cnet @classmethod def from_adjacency(cls, inputfile): """ Instantiate the class using an adjacency list Parameters ========== ---------- inputfile : str The input file containing the graph representation Returns ------- : object A Network graph object Examples -------- >>> from autocnet.examples import get_path >>> inputfile = get_path('adjacency.json') >>> candidate_graph = network.CandidateGraph.from_adjacency(inputfile) """ #TODO: This is better as a generic reader that tries drivers until # a valid dict is returned. adjacency_dict = io_json.read_json(inputfile) return cls(adjacency_dict) Loading Loading
.travis.yml +3 −1 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ python: - "3.5" before_install: install: # We do this conditionally because it saves us some downloading if the # version is the same. Loading @@ -26,11 +27,12 @@ install: - conda info -a # Create a virtual env and install dependencies - conda create -y -q -n test-env python=$TRAVIS_PYTHON_VERSION nose gdal numpy scipy pandas - conda create -y -q -n test-env python=$TRAVIS_PYTHON_VERSION nose gdal numpy pillow scipy pandas networkx # Activate the env - source activate test-env # Install the non-conda packages if required, requirements.txt duplicates are ignored - conda install -c https://conda.binstar.org/menpo opencv3 - conda install -c osgeo proj4 - pip install -r requirements.txt - pip install coverage Loading
autocnet/control/control.py +2 −0 Original line number Diff line number Diff line Loading @@ -2,6 +2,8 @@ from time import gmtime, strftime import pandas as pd POINT_TYPE = 2 MEASURE_TYPE = 2 class CSeries(pd.Series): """ Loading
autocnet/fileio/io_gdal.py +1 −0 Original line number Diff line number Diff line Loading @@ -350,6 +350,7 @@ class GeoDataset(object): xextent, yextent).astype(dtype) return array def array_to_raster(array, file_name, projection=None, geotransform=None, outformat='GTiff', ndv=None): Loading
autocnet/graph/network.py +97 −7 Original line number Diff line number Diff line from collections import Hashable from networkx import DiGraph import networkx as nx import pandas as pd from autocnet.control.control import C, POINT_TYPE, MEASURE_TYPE from autocnet.fileio import io_json class CandidateGraph(DiGraph): class CandidateGraph(nx.Graph): """ A NetworkX derived directed graph to store candidate overlap images. Loading @@ -12,8 +18,6 @@ class CandidateGraph(DiGraph): Attributes ---------- """ #TODO: This would be better with composition, and then dispatch the # network X calls to the graph object. def __init__(self,*args, **kwargs): super(CandidateGraph, self).__init__(*args, **kwargs) Loading @@ -36,6 +40,7 @@ class CandidateGraph(DiGraph): Parameters ========== outputfile : str PATH where the JSON will be written """ Loading @@ -44,18 +49,103 @@ class CandidateGraph(DiGraph): adjacency_dict[n] = self.neighbors(n) io_json.write_json(adjacency_dict, outputfile) def add_matches(self, source_node, 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 with the pandas dataframe. Parameters ---------- source_node : str The identifier for the node matches : dataframe The pandas dataframe containing the matches """ #TODO: This really belongs in an outlier detection matcher class, not here. # Remove erroneous self neighbors matches = matches.loc[matches['matched_to'] != source_node] groups = matches.groupby('matched_to') for destination_node, group in groups: try: edge = self[source_node][destination_node] except: edge = self[destination_node][source_node] if 'matches' in edge.keys(): df = edge['matches'] edge['matches'] = pd.merge(df, matches, left_on='queryIdx', right_on='trainIdx') else: edge['matches'] = matches def to_cnet(self): """ Returns ------- cnet : C A control network object """ data = [] point_ids = [] serials = [] for source, destination, attributes in self.edges_iter(data=True): for i, row in attributes['matches'].iterrows(): # Get the source and destination x,y coordinates for matches source_idx = row['queryIdx_x'] source_keypoints = (self.node[source]['keypoints'][source_idx].pt[0], self.node[source]['keypoints'][source_idx].pt[1]) destination_idx = row['queryIdx_y'] destination_keypoints = (self.node[destination]['keypoints'][destination_idx].pt[0], self.node[destination]['keypoints'][destination_idx].pt[1]) data.append(source_keypoints) data.append(destination_keypoints) serials.append(source) serials.append(destination) point_ids.append(i) point_ids.append(i) point_types = [2] * len(point_ids) measure_types = [2] * len(point_ids) multi_index = pd.MultiIndex.from_tuples(list(zip(point_ids,point_types, serials, measure_types))) columns = ['x', 'y'] cnet = C(data, index=multi_index, columns=columns) # TODO: This method assumes a 2 image match and should be generalized to build an n-image C object return cnet @classmethod def from_adjacency(cls, inputfile): """ Instantiate the class using an adjacency list Parameters ========== ---------- inputfile : str The input file containing the graph representation Returns ------- : object A Network graph object Examples -------- >>> from autocnet.examples import get_path >>> inputfile = get_path('adjacency.json') >>> candidate_graph = network.CandidateGraph.from_adjacency(inputfile) """ #TODO: This is better as a generic reader that tries drivers until # a valid dict is returned. adjacency_dict = io_json.read_json(inputfile) return cls(adjacency_dict) Loading