Commit f36a33da authored by Jay's avatar Jay Committed by jay
Browse files

Remove unused files and add tests.

parent 1de52905
Loading
Loading
Loading
Loading
+0 −100
Changes for autocnet/fileio/ControlNetFileV0002.py: 0 added lines, 100 removed lines.
Original line number Diff line number Diff line
from protobuf3.fields import MessageField, EnumField, StringField, BoolField, Int32Field, DoubleField
from enum import Enum
from protobuf3.message import Message


class ControlNetFileHeaderV0002(Message):
    pass


class ControlPointFileEntryV0002(Message):

    class PointType(Enum):
        Free = 2
        Constrained = 3
        Fixed = 4
        obsolete_Tie = 0
        obsolete_Ground = 1

    class AprioriSource(Enum):
        NA = 0
        User = 1
        AverageOfMeasures = 2
        Reference = 3
        Ellipsoid = 4
        DEM = 5
        Basemap = 6
        BundleSolution = 7

    class PointLogData(Message):
        pass

    class Measure(Message):

        class MeasureType(Enum):
            Candidate = 0
            Manual = 1
            RegisteredPixel = 2
            RegisteredSubPixel = 3

        class MeasureLogData(Message):
            pass

ControlNetFileHeaderV0002.add_field('networkId', StringField(field_number=1, required=True))
ControlNetFileHeaderV0002.add_field('targetName', StringField(field_number=2, required=True))
ControlNetFileHeaderV0002.add_field('created', StringField(field_number=3, optional=True))
ControlNetFileHeaderV0002.add_field('lastModified', StringField(field_number=4, optional=True))
ControlNetFileHeaderV0002.add_field('description', StringField(field_number=5, optional=True))
ControlNetFileHeaderV0002.add_field('userName', StringField(field_number=6, optional=True))
ControlNetFileHeaderV0002.add_field('pointMessageSizes', Int32Field(field_number=7, repeated=True))

ControlPointFileEntryV0002.PointLogData.add_field('doubleDataType', Int32Field(field_number=1, optional=True))
ControlPointFileEntryV0002.PointLogData.add_field('doubleDataValue', DoubleField(field_number=2, optional=True))
ControlPointFileEntryV0002.PointLogData.add_field('boolDataType', Int32Field(field_number=3, optional=True))
ControlPointFileEntryV0002.PointLogData.add_field('boolDataValue', BoolField(field_number=4, optional=True))
ControlPointFileEntryV0002.Measure.MeasureLogData.add_field('doubleDataType', Int32Field(field_number=1, optional=True))
ControlPointFileEntryV0002.Measure.MeasureLogData.add_field('doubleDataValue', DoubleField(field_number=2, optional=True))
ControlPointFileEntryV0002.Measure.MeasureLogData.add_field('boolDataType', Int32Field(field_number=3, optional=True))
ControlPointFileEntryV0002.Measure.MeasureLogData.add_field('boolDataValue', BoolField(field_number=4, optional=True))
ControlPointFileEntryV0002.Measure.add_field('serialnumber', StringField(field_number=1, required=True))
ControlPointFileEntryV0002.Measure.add_field('type', EnumField(field_number=2, required=True, enum_cls=ControlPointFileEntryV0002.Measure.MeasureType))
ControlPointFileEntryV0002.Measure.add_field('sample', DoubleField(field_number=3, optional=True))
ControlPointFileEntryV0002.Measure.add_field('line', DoubleField(field_number=4, optional=True))
ControlPointFileEntryV0002.Measure.add_field('sampleResidual', DoubleField(field_number=5, optional=True))
ControlPointFileEntryV0002.Measure.add_field('lineResidual', DoubleField(field_number=6, optional=True))
ControlPointFileEntryV0002.Measure.add_field('choosername', StringField(field_number=7, optional=True))
ControlPointFileEntryV0002.Measure.add_field('datetime', StringField(field_number=8, optional=True))
ControlPointFileEntryV0002.Measure.add_field('editLock', BoolField(field_number=9, optional=True))
ControlPointFileEntryV0002.Measure.add_field('ignore', BoolField(field_number=10, optional=True))
ControlPointFileEntryV0002.Measure.add_field('jigsawRejected', BoolField(field_number=11, optional=True))
ControlPointFileEntryV0002.Measure.add_field('diameter', DoubleField(field_number=12, optional=True))
ControlPointFileEntryV0002.Measure.add_field('apriorisample', DoubleField(field_number=13, optional=True))
ControlPointFileEntryV0002.Measure.add_field('aprioriline', DoubleField(field_number=14, optional=True))
ControlPointFileEntryV0002.Measure.add_field('samplesigma', DoubleField(field_number=15, optional=True))
ControlPointFileEntryV0002.Measure.add_field('linesigma', DoubleField(field_number=16, optional=True))
ControlPointFileEntryV0002.Measure.add_field('log', MessageField(field_number=17, repeated=True, message_cls=ControlPointFileEntryV0002.Measure.MeasureLogData))
ControlPointFileEntryV0002.add_field('id', StringField(field_number=1, required=True))
ControlPointFileEntryV0002.add_field('type', EnumField(field_number=2, required=True, enum_cls=ControlPointFileEntryV0002.PointType))
ControlPointFileEntryV0002.add_field('chooserName', StringField(field_number=3, optional=True))
ControlPointFileEntryV0002.add_field('datetime', StringField(field_number=4, optional=True))
ControlPointFileEntryV0002.add_field('editLock', BoolField(field_number=5, optional=True))
ControlPointFileEntryV0002.add_field('ignore', BoolField(field_number=6, optional=True))
ControlPointFileEntryV0002.add_field('jigsawRejected', BoolField(field_number=7, optional=True))
ControlPointFileEntryV0002.add_field('referenceIndex', Int32Field(field_number=8, optional=True))
ControlPointFileEntryV0002.add_field('aprioriSurfPointSource', EnumField(field_number=9, optional=True, enum_cls=ControlPointFileEntryV0002.AprioriSource))
ControlPointFileEntryV0002.add_field('aprioriSurfPointSourceFile', StringField(field_number=10, optional=True))
ControlPointFileEntryV0002.add_field('aprioriRadiusSource', EnumField(field_number=11, optional=True, enum_cls=ControlPointFileEntryV0002.AprioriSource))
ControlPointFileEntryV0002.add_field('aprioriRadiusSourceFile', StringField(field_number=12, optional=True))
ControlPointFileEntryV0002.add_field('latitudeConstrained', BoolField(field_number=13, optional=True))
ControlPointFileEntryV0002.add_field('longitudeConstrained', BoolField(field_number=14, optional=True))
ControlPointFileEntryV0002.add_field('radiusConstrained', BoolField(field_number=15, optional=True))
ControlPointFileEntryV0002.add_field('aprioriX', DoubleField(field_number=16, optional=True))
ControlPointFileEntryV0002.add_field('aprioriY', DoubleField(field_number=17, optional=True))
ControlPointFileEntryV0002.add_field('aprioriZ', DoubleField(field_number=18, optional=True))
ControlPointFileEntryV0002.add_field('aprioriCovar', DoubleField(field_number=19, repeated=True))
ControlPointFileEntryV0002.add_field('adjustedX', DoubleField(field_number=20, optional=True))
ControlPointFileEntryV0002.add_field('adjustedY', DoubleField(field_number=21, optional=True))
ControlPointFileEntryV0002.add_field('adjustedZ', DoubleField(field_number=22, optional=True))
ControlPointFileEntryV0002.add_field('adjustedCovar', DoubleField(field_number=23, repeated=True))
ControlPointFileEntryV0002.add_field('log', MessageField(field_number=24, repeated=True, message_cls=ControlPointFileEntryV0002.PointLogData))
ControlPointFileEntryV0002.add_field('measures', MessageField(field_number=25, repeated=True, message_cls=ControlPointFileEntryV0002.Measure))

autocnet/graph/health.py

deleted100644 → 0
+0 −3
Changes for autocnet/graph/health.py: 0 added lines, 3 removed lines.
Original line number Diff line number Diff line
class Health(object):
    pass
+4 −3
Changes for autocnet/matcher/health.py: 4 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -18,9 +18,10 @@ class EdgeHealth(object):
        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)
        for k, v in kwargs.items():
            if hasattr(self, k):
                print(k)
                setattr(self, k, v)

    def recompute_health(self):
        """
+7 −58
Changes for autocnet/matcher/outlier_detector.py: 7 added lines, 58 removed lines.
Original line number Diff line number Diff line
@@ -159,7 +159,10 @@ class SpatialSuppression(Observable):

    @property
    def nvalid(self):
        try:
            return self.mask.sum()
        except:
            return None

    @property
    def k(self):
@@ -185,16 +188,6 @@ class SpatialSuppression(Observable):
        """
        Suppress subpixel registered points to that k +- k * error_k
        points, with good spatial distribution, remain

        Adds a suppression mask to the edge mask dataframe.

        Parameters
        ----------
        k : int
            The desired number of output points

        error_k : float
                  [0,1) The acceptable epsilon
        """
        if self.k > len(self.df):
            warnings.warn('Only {} valid points, but {} points requested'.format(len(self.df), self.k))
@@ -206,6 +199,7 @@ class SpatialSuppression(Observable):
        while True:
            mid_idx = int((min_idx + max_idx) / 2)
            r = search_space[mid_idx]

            cell_size = cell_sizes[mid_idx]
            n_x_cells = int(self.domain[0] / cell_size)
            n_y_cells = int(self.domain[1] / cell_size)
@@ -263,6 +257,9 @@ class SpatialSuppression(Observable):
            elif len(result) < self.k:
                # The radius is too large
                max_idx = mid_idx
            elif min_idx == mid_idx or mid_idx == max_idx:
                warnings.warn('Unable to optimally solve.  Returning with {} points'.format(len(result)))
                break

        self.mask = pd.Series(False, self.df.index)
        self.mask.loc[list(result)] = True
@@ -434,51 +431,3 @@ def compute_homography(kp1, kp2, method='ransac', **kwargs):
    if mask is not None:
        mask = mask.astype(bool)
    return transformation_matrix, mask


# TODO: CITATION and better design?
def adaptive_non_max_suppression(keypoints, n, robust):
    """
    Select the top n keypoints, using Adaptive Non-Maximal Suppression (see: Brown (2005) [Brown2005]_)
    to rank the keypoints in order of largest minimum suppression
    radius. A mask with only the positions of the top n keypoints set to 1 (and all else set to 0) is returned.

    Parameters
    ----------
    keypoints : list
               List of KeyPoint objects from a node of the graph or equivalently, for 1 image.

    n : int
        The number of top-ranked keypoints to return.

    Returns
    -------
    keypoint_mask : list
                    A list containing a 1 in the positions of the top n selected keypoints and 0 in the positions
                    of all the other keypoints.
    """
    minimum_suppression_radius = {}
    for i, kp1 in keypoints.iterrows():
        x1 = kp1['x']
        y1 = kp1['y']
        temp = []
        for j, kp2 in keypoints.iterrows(): #includes kp1 for now
            if kp1['response'] < robust*kp2['response']:
                x2 = kp2['x']
                y2 = kp2['y']
                temp.append(np.sqrt((x2-x1)**2 + (y2-y1)**2))
        if(len(temp) > 0):
            minimum_suppression_radius[i] = np.min(np.array(temp))
        else:
            minimum_suppression_radius[i] = np.nan
    df = pd.DataFrame(list(minimum_suppression_radius.items()), columns=['keypoint', 'radius'])
    top_n = df.sort_values(by='radius', ascending=False).head(n)
    temp_df = df.mask(df.radius < top_n.radius.min(), other=np.nan)
    temp_df = temp_df.where(np.isnan(temp_df.keypoint), other=1)
    temp_df = temp_df.mask(np.isnan(temp_df.keypoint), other=0)
    return np.array(temp_df.radius, dtype=np.bool)




autocnet/matcher/ransac.py

deleted100644 → 0
+0 −126
Changes for autocnet/matcher/ransac.py: 0 added lines, 126 removed lines.
Original line number Diff line number Diff line
import numpy
import scipy # use numpy if scipy unavailable
import scipy.linalg # use numpy if scipy unavailable

## Copyright (c) 2004-2007, Andrew D. Straw. All rights reserved.

## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are
## met:

##     * Redistributions of source code must retain the above copyright
##       notice, this list of conditions and the following disclaimer.

##     * Redistributions in binary form must reproduce the above
##       copyright notice, this list of conditions and the following
##       disclaimer in the documentation and/or other materials provided
##       with the distribution.

##     * Neither the name of the Andrew D. Straw nor the names of its
##       contributors may be used to endorse or promote products derived
##       from this software without specific prior written permission.

## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



class LinearLeastSquaresModel:
    """linear system solved using linear least squares

    This class serves as an example that fulfills the model interface
    needed by the ransac() function.

    """
    def __init__(self,input_columns,output_columns,debug=False):
        self.input_columns = input_columns
        self.output_columns = output_columns
        self.debug = debug
    def fit(self, data):
        A = numpy.vstack([data[:,i] for i in self.input_columns]).T
        B = numpy.vstack([data[:,i] for i in self.output_columns]).T
        x,resids,rank,s = scipy.linalg.lstsq(A,B)
        return x
    def get_error( self, data, model):
        A = numpy.vstack([data[:,i] for i in self.input_columns]).T
        B = numpy.vstack([data[:,i] for i in self.output_columns]).T
        B_fit = scipy.dot(A,model)
        err_per_point = numpy.sum((B-B_fit)**2,axis=1) # sum squared error per row
        return err_per_point

def test():
    # generate perfect input data

    n_samples = 500
    n_inputs = 1
    n_outputs = 1
    A_exact = 20*numpy.random.random((n_samples,n_inputs) )
    perfect_fit = 60*numpy.random.normal(size=(n_inputs,n_outputs) ) # the model
    B_exact = scipy.dot(A_exact,perfect_fit)
    assert B_exact.shape == (n_samples,n_outputs)

    # add a little gaussian noise (linear least squares alone should handle this well)
    A_noisy = A_exact + numpy.random.normal(size=A_exact.shape )
    B_noisy = B_exact + numpy.random.normal(size=B_exact.shape )

    if 1:
        # add some outliers
        n_outliers = 100
        all_idxs = numpy.arange( A_noisy.shape[0] )
        numpy.random.shuffle(all_idxs)
        outlier_idxs = all_idxs[:n_outliers]
        non_outlier_idxs = all_idxs[n_outliers:]
        A_noisy[outlier_idxs] =  20*numpy.random.random((n_outliers,n_inputs) )
        B_noisy[outlier_idxs] = 50*numpy.random.normal(size=(n_outliers,n_outputs) )

    # setup model

    all_data = numpy.hstack( (A_noisy,B_noisy) )
    input_columns = range(n_inputs) # the first columns of the array
    output_columns = [n_inputs+i for i in range(n_outputs)] # the last columns of the array
    debug = False
    model = LinearLeastSquaresModel(input_columns,output_columns,debug=debug)

    linear_fit,resids,rank,s = scipy.linalg.lstsq(all_data[:,input_columns],
                                                  all_data[:,output_columns])

    # run RANSAC algorithm
    ransac_fit, ransac_data = ransac(all_data,model,
                                     50, 1000, 7e3, 300, # misc. parameters
                                     debug=debug,return_all=True)
    if 1:
        import pylab

        sort_idxs = numpy.argsort(A_exact[:,0])
        A_col0_sorted = A_exact[sort_idxs] # maintain as rank-2 array

        if 1:
            pylab.plot( A_noisy[:,0], B_noisy[:,0], 'k.', label='data' )
            pylab.plot( A_noisy[ransac_data['inliers'],0], B_noisy[ransac_data['inliers'],0], 'bx', label='RANSAC data' )
        else:
            pylab.plot( A_noisy[non_outlier_idxs,0], B_noisy[non_outlier_idxs,0], 'k.', label='noisy data' )
            pylab.plot( A_noisy[outlier_idxs,0], B_noisy[outlier_idxs,0], 'r.', label='outlier data' )
        pylab.plot( A_col0_sorted[:,0],
                    numpy.dot(A_col0_sorted,ransac_fit)[:,0],
                    label='RANSAC fit' )
        pylab.plot( A_col0_sorted[:,0],
                    numpy.dot(A_col0_sorted,perfect_fit)[:,0],
                    label='exact system' )
        pylab.plot( A_col0_sorted[:,0],
                    numpy.dot(A_col0_sorted,linear_fit)[:,0],
                    label='linear fit' )
        pylab.legend()
        pylab.show()

if __name__=='__main__':
    test()
Loading