Commit c3771da2 authored by jay's avatar jay
Browse files

merge from master

parents 9fbd0ba9 7f9248ab
Loading
Loading
Loading
Loading
+3 −1
Changes for .travis.yml: 3 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -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.
@@ -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
+2 −0
Changes for autocnet/control/control.py: 2 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@ from time import gmtime, strftime

import pandas as pd

POINT_TYPE = 2
MEASURE_TYPE = 2

class CSeries(pd.Series):
    """
+1 −0
Changes for autocnet/fileio/io_gdal.py: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -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):
+0 −0

Empty file deleted.

+97 −7
Changes for autocnet/graph/network.py: 97 added lines, 7 removed lines.
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.

@@ -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)
@@ -36,6 +40,7 @@ class CandidateGraph(DiGraph):

        Parameters
        ==========

        outputfile : str
                     PATH where the JSON will be written
        """
@@ -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