Commit 22185cc0 authored by jay's avatar jay
Browse files

fixed merge

parent d30cd568
Loading
Loading
Loading
Loading
+26 −5
Original line number Diff line number Diff line
@@ -67,11 +67,6 @@ class CandidateGraph(nx.Graph):
            e = self.edge[s][d]
            e.source = self.node[s]
            e.destination = self.node[d]
            #del self.adj[d][s]

        # Add the Edge class as a edge data structure
        #for s, d, edge in self.edges_iter(data=True):
            #self.edge[s][d] = Edge(self.node[s], self.node[d])

    @classmethod
    def from_graph(cls, graph):
@@ -373,6 +368,32 @@ class CandidateGraph(nx.Graph):
        """
        _, self.clusters = func(self, *args, **kwargs)

    def compute_triangular_cycles(self):
        """
        Find all cycles of length 3.  This is similar
         to cycle_basis (networkX), but returns all cycles.
         As opposed to all basis cycles.

        Returns
        -------
        cycles : list
                 A list of cycles in the form [(a,b,c), (c,d,e)],
                 where letrers indicate node identifiers

        Examples
        --------
        >>> g = CandidateGraph()
        >>> g.add_edges_from([(0,1), (0,2), (1,2), (0,3), (1,3), (2,3)])
        >>> g.compute_triangular_cycles()
        [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
        """
        cycles = []
        for s, d in self.edges_iter():
            for n in self.nodes():
                if(s,n) in self.edges() and (d,n) in self.edges():
                    cycles.append((s,d,n))
        return cycles

    def apply_func_to_edges(self, function, *args, **kwargs):
        """
        Iterates over edges using an optional mask and and applies the given function.
+12 −7
Original line number Diff line number Diff line
@@ -144,13 +144,13 @@ class Node(dict, MutableMapping):
        """
        if hasattr(self, '_keypoints'):
            try:
                return self._keypoints.iloc[index]
                return self._keypoints.loc[index]
            except:
                return self._keypoints
        else:
            return None

    def get_keypoint_coordinates(self, index=None):
    def get_keypoint_coordinates(self, index=None, homogeneous=False):
        """
        Return the coordinates of the keypoints without any ancillary data

@@ -159,16 +159,21 @@ class Node(dict, MutableMapping):
        index : iterable
                indices for of the keypoints to return

        homogeneous : bool
                      If True, return homogeneous coordinates in the form
                      [x, y, 1]. Default: False

        Returns
        -------
         : dataframe
           A pandas dataframe of keypoint coordinates
        """
        keypoints = self.get_keypoints(index=index)
        try:
            return keypoints[['x', 'y']]
        except:
            return None
        keypoints = self.get_keypoints(index=index)[['x', 'y']]

        if homogeneous:
            keypoints['homogeneous'] = 1

        return keypoints

    def extract_features(self, array, **kwargs):
        """
+16 −18
Original line number Diff line number Diff line
@@ -138,17 +138,17 @@ class SpatialSuppression(Observable):

    """

    def __init__(self, df, domain, min_radius=2, k=250, error_k=0.1):
    def __init__(self, df, domain, min_radius=1, k=250, error_k=0.1):
        columns = df.columns
        for i in ['x', 'y', 'strength']:
            if i not in columns:
                raise ValueError('The dataframe is missing a {} column.'.format(i))
        self._df = df.sort_values(by=['strength'], ascending=False).copy()
        self.df = df.sort_values(by=['strength'], ascending=False).copy()
        self.max_radius = max(domain)
        self.min_radius = min_radius
        self.domain = domain
        self.mask = None
        self._k = k
        self.k = k
        self._error_k = error_k

        self.attrs = ['mask', 'k', 'error_k']
@@ -164,14 +164,6 @@ class SpatialSuppression(Observable):
        except:
            return None

    @property
    def k(self):
        return self._k

    @k.setter
    def k(self, v):
        self._k = v

    @property
    def error_k(self):
        return self._error_k
@@ -180,23 +172,23 @@ class SpatialSuppression(Observable):
    def error_k(self, v):
        self._error_k = v

    @property
    def df(self):
        return self._df

    def suppress(self):
        """
        Suppress subpixel registered points to that k +- k * error_k
        points, with good spatial distribution, remain
        """
        process = True
        if self.k > len(self.df):
            warnings.warn('Only {} valid points, but {} points requested'.format(len(self.df), self.k))
            self.k = len(self.df)
            result = self.df.index
            process = False
        search_space = np.linspace(self.min_radius, self.max_radius / 16, 250)
        cell_sizes = (search_space / math.sqrt(2)).astype(np.int)
        min_idx = 0
        max_idx = len(search_space) - 1
        while True:

        while process:
            mid_idx = int((min_idx + max_idx) / 2)
            r = search_space[mid_idx]

@@ -228,6 +220,7 @@ class SpatialSuppression(Observable):
                    pts.append((p[['x', 'y']]))
                    if len(result) > self.k + self.k * self.error_k:
                        # Too many points, break
                        print('TooMany')
                        min_idx = mid_idx
                        break

@@ -253,13 +246,18 @@ class SpatialSuppression(Observable):

            #  Check break conditions
            if self.k - self.k * self.error_k <= len(result) <= self.k + self.k * self.error_k:
                break
                print('Just right')
                process = False
            elif len(result) < self.k:
                # The radius is too large
                print('TOOFEW')
                max_idx = mid_idx
                if min_idx == max_idx:
                    process = False
            elif min_idx == mid_idx or mid_idx == max_idx:
                warnings.warn('Unable to optimally solve.  Returning with {} points'.format(len(result)))
                break
                process = False


        self.mask = pd.Series(False, self.df.index)
        self.mask.loc[list(result)] = True
+10 −1
Original line number Diff line number Diff line
@@ -93,7 +93,6 @@ class TestUtils(unittest.TestCase):
        self.assertEqual(pts.shape, (25,3))
        np.testing.assert_array_equal(pts[:, -1], np.ones(25))


    def test_remove_field_name(self):
        starray = np.array([(1 ,2.,'String'), (2, 3.,"String2")],
              dtype=[('index', 'i4'),('bar', 'f4'), ('baz', 'S10')])
@@ -101,3 +100,13 @@ class TestUtils(unittest.TestCase):
              dtype=[('bar', 'f4'), ('baz', 'S10')])
        cleaned_array = utils.remove_field_name(starray, 'index')
        np.testing.assert_array_equal(cleaned_array, truth)

    def test_normalize_vector(self):
        x = np.array([1,1,1], dtype=np.float)
        y = utils.normalize_vector(x)
        np.testing.assert_array_almost_equal(np.array([ 0.70710678,  0.70710678,  0.70710678]), y)

        x = np.repeat(np.arange(4), 3).reshape(-1, 3)
        y = utils.normalize_vector(x)
        truth = np.tile(np.array([ 0.70710678,  0.70710678,  0.70710678]), 4)
        np.testing.assert_array_almost_equal(truth, y)
+34 −0
Original line number Diff line number Diff line
from functools import reduce
import numpy as np
import pandas as pd


def normalize_vector(line):
    """
    Normalize a standard form line

    Parameters
    ----------
    line : ndarray
           Standard line form coefficients

    Returns
    -------
    line : ndarray
           The normalized line

    Examples
    --------
    >>> x = np.random.random((3,3))
    >>> normalize_vector(x)
    array([[ 0.88280225,  0.4697448 ,  0.11460811],
       [ 0.26090555,  0.96536433,  0.91648305],
       [ 0.58271501,  0.81267657,  0.30796395]])
    """
    if isinstance(line, pd.DataFrame):
        line = line.values
    try:
        n = np.sqrt(line[:, 0]**2 + line[:, 1]**2).reshape(-1, 1)
    except:
        n = np.sqrt(line[0]**2 + line[1]**2)
    line /= n
    return line


def getnearest(iterable, value):
    """
Loading