Commit ac7b06ca authored by jay's avatar jay
Browse files

Merge remote-tracking branch 'upstream/dev'

parents 502d4208 0e1240b8
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -392,7 +392,8 @@ class GeoDataset(object):
            lon, lat, _ = self.coordinate_transformation.TransformPoint(x, y)
        except:
            lat = lon = None
            warnings.warn('Unable to compute pixel to geographic conversion without projection information.')
            warnings.warn('Unable to compute pixel to geographic conversion without '
                          'projection information for {}'.format(self.base_name))

        return lat, lon

+9 −0
Original line number Diff line number Diff line
@@ -22,3 +22,12 @@ def delete_dir(dir):
          Remove a directory
    """
    shutil.rmtree(dir)


def file_to_list(file):
    with open(file, 'r') as f:
        file_list = f.readlines()
        file_list = map(str.rstrip, file_list)
        file_list = filter(None, file_list)

    return file_list
+7 −7
Original line number Diff line number Diff line
@@ -228,11 +228,11 @@ class Edge(dict, MutableMapping):

        # Grab the full images, or handles
        if tiled is True:
            s_img = self.source.handle
            d_img = self.destination.handle
            s_img = self.source.geodata
            d_img = self.destination.geodata
        else:
            s_img = self.source.handle.read_array()
            d_img = self.destination.handle.read_array()
            s_img = self.source.geodata.read_array()
            d_img = self.destination.geodata.read_array()

        source_image = (matches.iloc[0]['source_image'])

@@ -292,7 +292,7 @@ class Edge(dict, MutableMapping):
            raise AttributeError('This edge does not yet have any matches computed.')

        matches, mask = self._clean(clean_keys)
        domain = self.source.handle.raster_size
        domain = self.source.geodata.raster_size

        # Massage the dataframe into the correct structure
        coords = self.source.get_keypoint_coordinates()
@@ -357,8 +357,8 @@ class Edge(dict, MutableMapping):
               The estimated area
        """

        source_geom = self.source.handle.pixel_polygon
        destination_geom = self.destination.handle.pixel_polygon
        source_geom = self.source.geodata.pixel_polygon
        destination_geom = self.destination.geodata.pixel_polygon

        # Project using the homography
        vertices_to_project = destination_geom.vertices
+33 −33
Original line number Diff line number Diff line
import itertools
import math
import os
import warnings

import dill as pickle
import networkx as nx
import numpy as np
import pandas as pd

from autocnet.fileio.io_gdal import GeoDataset
from autocnet.fileio import io_hdf
from autocnet.control.control import C
from autocnet.fileio import io_hdf
from autocnet.fileio import io_json
from autocnet.matcher.matcher import FlannMatcher
import autocnet.matcher.suppression_funcs as spf
from autocnet.fileio import io_utils
from autocnet.fileio.io_gdal import GeoDataset
from autocnet.graph import markov_cluster
from autocnet.graph.edge import Edge
from autocnet.graph.node import Node
from autocnet.graph import markov_cluster
from autocnet.matcher.matcher import FlannMatcher
from autocnet.vis.graph_view import plot_graph


@@ -44,7 +46,6 @@ class CandidateGraph(nx.Graph):
        self.node_counter = 0
        node_labels = {}
        self.node_name_map = {}
        self.graph_masks = pd.DataFrame()

        for node_name in self.nodes():
            image_name = os.path.basename(node_name)
@@ -107,10 +108,8 @@ class CandidateGraph(nx.Graph):
        : object
          A Network graph object
        """
        if not isinstance(filelist, list):
            with open(filelist, 'r') as f:
                filelist = f.readlines()
                filelist = map(str.rstrip, filelist)
        if isinstance(filelist, str):
            filelist = io_utils.file_to_list(filelist)

        # TODO: Reject unsupported file formats + work with more file formats
        if basepath:
@@ -120,22 +119,29 @@ class CandidateGraph(nx.Graph):

        # This is brute force for now, could swap to an RTree at some point.
        adjacency_dict = {}
        valid_datasets = []

        for i, j in itertools.permutations(datasets,2):
            if not i.file_name in adjacency_dict.keys():
        for i in datasets:
            adjacency_dict[i.file_name] = []
            if not j.file_name in adjacency_dict.keys():
                adjacency_dict[j.file_name] = []

            fp = i.footprint
            if fp and fp.IsValid():
                valid_datasets.append(i)
            else:
                warnings.warn('Missing or invalid geospatial data for {}'.format(i.base_name))

        # Grab the footprints and test for intersection
        for i, j in itertools.permutations(valid_datasets, 2):
            i_fp = i.footprint
            j_fp = j.footprint

            try:
                if i_fp.Intersects(j_fp):
                    adjacency_dict[i.file_name].append(j.file_name)
                    adjacency_dict[j.file_name].append(i.file_name)
            except: # no geospatial information embedded in the images
                pass
            except:
                warnings.warn('Failed to calculated intersection between {} and {}'.format(i, j))

        return cls(adjacency_dict)


@@ -297,6 +303,11 @@ class CandidateGraph(nx.Graph):
            descriptors = node.descriptors
            # Load the neighbors of the current node into the FLANN matcher
            neighbors = self.neighbors(i)

            # if node has no neighbors, skip
            if not neighbors:
                continue

            for n in neighbors:
                neighbor_descriptors = self.node[n].descriptors
                self._fl.add(neighbor_descriptors, n)
@@ -362,7 +373,7 @@ class CandidateGraph(nx.Graph):
        """
        _, self.clusters = func(self, *args, **kwargs)

    def apply_func_to_edges(self, function, *args, graph_mask_keys=[], **kwargs):
    def apply_func_to_edges(self, function, *args, **kwargs):
        """
        Iterates over edges using an optional mask and and applies the given function.
        If func is not an attribute of Edge, raises AttributeError
@@ -373,20 +384,12 @@ class CandidateGraph(nx.Graph):
        graph_mask_keys : list
                          of keys in graph_masks
        """

        if graph_mask_keys:
            merged_graph_mask = self.graph_masks[graph_mask_keys].all(axis=1)
            edges_to_iter = merged_graph_mask[merged_graph_mask].index
        else:
            edges_to_iter = self.edges()

        if not isinstance(function, str):
            function = function.__name__

        for s, d in edges_to_iter:
            curr_edge = self.get_edge_data(s, d)
        for s, d, edge in self.edges_iter(data=True):
            try:
                func = getattr(curr_edge, function)
                func = getattr(edge, function)
            except:
                raise AttributeError(function, ' is not an attribute of Edge')
            else:
@@ -403,11 +406,8 @@ class CandidateGraph(nx.Graph):
           boolean mask for edges in the minimum spanning tree
        """

        graph_mask = pd.Series(False, index=self.edges())
        self.graph_masks['mst'] = graph_mask

        mst = nx.minimum_spanning_tree(self)
        self.graph_masks['mst'][mst.edges()] = True
        return self.create_edge_subgraph(mst.edges())

    def to_filelist(self):
        """
+8 −8
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ class Node(dict, MutableMapping):
                 Name of the image, with extension
    image_path : str
                 Relative or absolute PATH to the image
    handle : object
    geodata : object
             File handle to the object
    keypoints : dataframe
                With columns, x, y, and response
@@ -59,10 +59,10 @@ class Node(dict, MutableMapping):
        """.format(self.node_id, self.image_name, self.image_path,
                   self.nkeypoints, self.masks, self.__class__)
    @property
    def handle(self):
        if not getattr(self, '_handle', None):
            self._handle = GeoDataset(self.image_path)
        return self._handle
    def geodata(self):
        if not getattr(self, '_geodata', None):
            self._geodata = GeoDataset(self.image_path)
        return self._geodata

    @property
    def nkeypoints(self):
@@ -123,7 +123,7 @@ class Node(dict, MutableMapping):
               The band to read, default 1
        """

        array = self.handle.read_array(band=band)
        array = self.geodata.read_array(band=band)
        return bytescale(array)

    def get_keypoints(self, index=None):
@@ -272,7 +272,7 @@ class Node(dict, MutableMapping):
        if not hasattr(self, '_keypoints'):
            raise AttributeError('No keypoints extracted for this node.')

        domain = self.handle.raster_size
        domain = self.geodata.raster_size
        self._keypoints['strength'] = self._keypoints.apply(func, axis=1)

        if not hasattr(self, 'suppression'):
@@ -297,7 +297,7 @@ class Node(dict, MutableMapping):
        ratio : float
                The ratio of convex hull area to total area.
        """
        ideal_area = self.handle.pixel_area
        ideal_area = self.geodata.pixel_area
        if not hasattr(self, '_keypoints'):
            raise AttributeError('Keypoints must be extracted already, they have not been.')

Loading