Loading .coveragerc +2 −12 Original line number Diff line number Diff line Loading @@ -2,19 +2,9 @@ source = autocnet [report] omit = autocnet/fileio/ControlNetFileV0002_pb2.py autocnet/vis/graph_view.py autocnet/fileio/sqlalchemy_json/* autocnet/fileio/io_multibandimager.py autocnet/fileio/io_moon_minerology_mapper.py autocnet/fileio/header_parser.py autocnet/fileio/io_ccs.py autocnet/fileio/io_jsc.py autocnet/fileio/io_edr.py autocnet/fileio/lookup.py autocnet/fileio/utils.py autocnet/utils/folds.py autocnet/spectral/* autocnet/__init__.py autocnet/matcher/cuda_* bin/* */tests/* exclude_lines = Loading .travis.yml +6 −8 Original line number Diff line number Diff line Loading @@ -14,8 +14,6 @@ os: - linux - osx before_install: install: # We do this conditionally because it saves us some downloading if the # version is the same. Loading Loading @@ -44,18 +42,18 @@ install: - conda config --add channels conda-forge - conda config --add channels menpo - conda config --add channels jlaura - conda install -c conda-forge numpy - conda install -c jlaura plio opencv3=3.0.0 - conda config --set ssl_verify false - conda install python=$PYTHON_VERSION - conda install -c conda-forge numpy opencv - conda install -c jlaura plio - conda install -c conda-forge vlfeat - conda install -c menpo cyvlfeat - pip install pillow pysal - conda install scipy networkx numexpr dill cython pyyaml matplotlib runipy # Development installation - conda install nose coverage sh anaconda-client - conda install pytest pytest-cov coverage sh anaconda-client - pip install coveralls - python runipynbs.py # Straight from the menpo team - if [["$TRAVIS_OS_NAME" == "osx"]]; then Loading @@ -67,7 +65,7 @@ install: - python condaci.py setup script: - nosetests --with-coverage --cover-package=autocnet - pytest --cov=autocnet after_success: # Upload to anaconda and push to coveralls Loading README.rst +2 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ AutoCNet Automated sparse control network generation to support photogrammetric control of planetary image data. * Documentation: https://autocnet.readthedocs.org. * Documentation: https://usgs-astrogeology.github.io/autocnet/ Installation Instructions ------------------------- Loading @@ -37,6 +37,6 @@ We suggest using Anaconda Python to install Autocnet within a virtual environmen * ``conda create -n <your_environment_name> python=3 && source activate <your_environment_name>`` 1. Bring up a command line and add three channels to your conda config (``~/condarc``): * ``conda config --add channels conda-forge`` * ``conda condig --add channels jlaura`` * ``conda config --add channels jlaura`` * ``conda config --add channels menpo`` 1. Finally, install autocnet: ``conda install -c jlaura autocnet-dev`` autocnet/__init__.py +44 −8 Original line number Diff line number Diff line import os import autocnet __version__ = "0.1.0" import warnings def get_data(filename): packagdir = autocnet.__path__[0] dirname = os.path.join(os.path.dirname(packagdir), 'data') fullname = os.path.join(dirname, filename) return fullname import autocnet import autocnet.examples import autocnet.camera Loading @@ -18,3 +12,45 @@ import autocnet.matcher import autocnet.transformation import autocnet.utils import autocnet.utils __version__ = "0.1.0" def get_data(filename): packagdir = autocnet.__path__[0] dirname = os.path.join(os.path.dirname(packagdir), 'data') fullname = os.path.join(dirname, filename) return fullname def cuda(enable=False, gpu=0): # Classes/Methods that can vary if GPU is available from autocnet.graph.node import Node from autocnet.graph.edge import Edge if enable: try: import cudasift as cs cs.PyInitCuda(gpu) # Here is where the GPU methods get patched into the class from autocnet.matcher.cuda_extractor import extract_features Node._extract_features = staticmethod(extract_features) from autocnet.matcher.cuda_matcher import match Edge.match = match from autocnet.matcher.cuda_decompose import decompose_and_match Edge.decompose_and_match = decompose_and_match except Exception: warning.warn('Failed to enable Cuda') return # Here is where the CPU methods get patched into the class from autocnet.matcher.feature_extractor import extract_features Node._extract_features = staticmethod(extract_features) from autocnet.matcher.feature_matcher import match Edge.match = match from autocnet.matcher.cpu_decompose import decompose_and_match Edge.decompose_and_match = decompose_and_match cuda() autocnet/camera/camera.py +41 −31 Original line number Diff line number Diff line import numpy as np from autocnet.camera.utils import crossform try: import cv2 except: cv2 = None def compute_epipoles(f): """ Loading @@ -21,9 +24,7 @@ def compute_epipoles(f): """ u, _, _ = np.linalg.svd(f) e = u[:, -1] e1 = np.array([[0, -e[2], e[1]], [e[2], 0, -e[0]], [-e[1], e[0], 0]]) e1 = crossform(e) return e, e1 Loading Loading @@ -102,24 +103,37 @@ def triangulate(pt, pt1, p, p1): pt = pt.T if pt1.shape[0] != 3: pt1 = pt1.T #if cv2: X = cv2.triangulatePoints(p, p1, pt[:2], pt1[:2]) # Homogenize X /= X[3] X /= X[3] # Homogenize return X """ # Stubbed in for a ticket addressing making OpenCV an optional dependency else: npts = len(pt) a = np.zeros((4, 4)) coords = np.empty((npts, 4)) coords[:] = 1 for i in range(npts): # Compute AX = 0 a[0] = pt[i][0] * p[2] - p[0] a[1] = pt[i][1] * p[2] - p[1] a[2] = pt1[i][0] * p1[2] - p1[0] a[3] = pt1[i][1] * p1[2] - p1[1] # v.T is a least squares solution that minimizes the error residual u, s, vh = np.linalg.svd(a) v = vh.T coords[i] = v[:,3] / (v[:,3][-1]) return coords.T """ def projection_error(p1, p, pt, pt1): """ Based on Hartley and Zisserman p.285 this function triangulates image correspondences and computes the reprojection error by back-projecting the points into the image. References ---------- .. [Hartley2003] This is the classic cost function (minimization problem) into the gold standard method for fundamental matrix estimation. Parameters ----------- Loading @@ -137,29 +151,25 @@ def projection_error(p1, p, pt, pt1): Returns ------- residuals : ndarray (n, 1) residuals for each correspondence cumulative_error : float sum of the residuals reproj_error : ndarray (n, 1) vector of reprojection errors """ # SciPy least squares solver needs a vector, so reshape back to a 3x4 c # camera matrix at each iteration if p1.shape != (3,4): p1 = p1.reshape(3,4) # Triangulate the correspondences xw_est = triangulate(pt, pt1, p, p1) # Back project and homogenize xhat = np.dot(p, xw_est) xhat /= xhat[2] x2hat = np.dot(p1, xw_est) x2hat /= x2hat[2] xhat = triangulate(pt, pt1, p, p1) xhat1 = xhat[:3] / xhat[2] xhat2 = p1.dot(xhat) xhat2 /= xhat2[2] # Compute residuals dist = (pt.T - xhat)**2 + (pt1.T - x2hat)**2 residuals = np.sum(dist, axis=0) reproj_error = np.sum(dist) # Compute error cost = (pt - xhat1)**2 + (pt1 - xhat2)**2 cost = np.sqrt(np.sum(cost, axis=0)) return residuals, reproj_error return cost Loading
.coveragerc +2 −12 Original line number Diff line number Diff line Loading @@ -2,19 +2,9 @@ source = autocnet [report] omit = autocnet/fileio/ControlNetFileV0002_pb2.py autocnet/vis/graph_view.py autocnet/fileio/sqlalchemy_json/* autocnet/fileio/io_multibandimager.py autocnet/fileio/io_moon_minerology_mapper.py autocnet/fileio/header_parser.py autocnet/fileio/io_ccs.py autocnet/fileio/io_jsc.py autocnet/fileio/io_edr.py autocnet/fileio/lookup.py autocnet/fileio/utils.py autocnet/utils/folds.py autocnet/spectral/* autocnet/__init__.py autocnet/matcher/cuda_* bin/* */tests/* exclude_lines = Loading
.travis.yml +6 −8 Original line number Diff line number Diff line Loading @@ -14,8 +14,6 @@ os: - linux - osx before_install: install: # We do this conditionally because it saves us some downloading if the # version is the same. Loading Loading @@ -44,18 +42,18 @@ install: - conda config --add channels conda-forge - conda config --add channels menpo - conda config --add channels jlaura - conda install -c conda-forge numpy - conda install -c jlaura plio opencv3=3.0.0 - conda config --set ssl_verify false - conda install python=$PYTHON_VERSION - conda install -c conda-forge numpy opencv - conda install -c jlaura plio - conda install -c conda-forge vlfeat - conda install -c menpo cyvlfeat - pip install pillow pysal - conda install scipy networkx numexpr dill cython pyyaml matplotlib runipy # Development installation - conda install nose coverage sh anaconda-client - conda install pytest pytest-cov coverage sh anaconda-client - pip install coveralls - python runipynbs.py # Straight from the menpo team - if [["$TRAVIS_OS_NAME" == "osx"]]; then Loading @@ -67,7 +65,7 @@ install: - python condaci.py setup script: - nosetests --with-coverage --cover-package=autocnet - pytest --cov=autocnet after_success: # Upload to anaconda and push to coveralls Loading
README.rst +2 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,7 @@ AutoCNet Automated sparse control network generation to support photogrammetric control of planetary image data. * Documentation: https://autocnet.readthedocs.org. * Documentation: https://usgs-astrogeology.github.io/autocnet/ Installation Instructions ------------------------- Loading @@ -37,6 +37,6 @@ We suggest using Anaconda Python to install Autocnet within a virtual environmen * ``conda create -n <your_environment_name> python=3 && source activate <your_environment_name>`` 1. Bring up a command line and add three channels to your conda config (``~/condarc``): * ``conda config --add channels conda-forge`` * ``conda condig --add channels jlaura`` * ``conda config --add channels jlaura`` * ``conda config --add channels menpo`` 1. Finally, install autocnet: ``conda install -c jlaura autocnet-dev``
autocnet/__init__.py +44 −8 Original line number Diff line number Diff line import os import autocnet __version__ = "0.1.0" import warnings def get_data(filename): packagdir = autocnet.__path__[0] dirname = os.path.join(os.path.dirname(packagdir), 'data') fullname = os.path.join(dirname, filename) return fullname import autocnet import autocnet.examples import autocnet.camera Loading @@ -18,3 +12,45 @@ import autocnet.matcher import autocnet.transformation import autocnet.utils import autocnet.utils __version__ = "0.1.0" def get_data(filename): packagdir = autocnet.__path__[0] dirname = os.path.join(os.path.dirname(packagdir), 'data') fullname = os.path.join(dirname, filename) return fullname def cuda(enable=False, gpu=0): # Classes/Methods that can vary if GPU is available from autocnet.graph.node import Node from autocnet.graph.edge import Edge if enable: try: import cudasift as cs cs.PyInitCuda(gpu) # Here is where the GPU methods get patched into the class from autocnet.matcher.cuda_extractor import extract_features Node._extract_features = staticmethod(extract_features) from autocnet.matcher.cuda_matcher import match Edge.match = match from autocnet.matcher.cuda_decompose import decompose_and_match Edge.decompose_and_match = decompose_and_match except Exception: warning.warn('Failed to enable Cuda') return # Here is where the CPU methods get patched into the class from autocnet.matcher.feature_extractor import extract_features Node._extract_features = staticmethod(extract_features) from autocnet.matcher.feature_matcher import match Edge.match = match from autocnet.matcher.cpu_decompose import decompose_and_match Edge.decompose_and_match = decompose_and_match cuda()
autocnet/camera/camera.py +41 −31 Original line number Diff line number Diff line import numpy as np from autocnet.camera.utils import crossform try: import cv2 except: cv2 = None def compute_epipoles(f): """ Loading @@ -21,9 +24,7 @@ def compute_epipoles(f): """ u, _, _ = np.linalg.svd(f) e = u[:, -1] e1 = np.array([[0, -e[2], e[1]], [e[2], 0, -e[0]], [-e[1], e[0], 0]]) e1 = crossform(e) return e, e1 Loading Loading @@ -102,24 +103,37 @@ def triangulate(pt, pt1, p, p1): pt = pt.T if pt1.shape[0] != 3: pt1 = pt1.T #if cv2: X = cv2.triangulatePoints(p, p1, pt[:2], pt1[:2]) # Homogenize X /= X[3] X /= X[3] # Homogenize return X """ # Stubbed in for a ticket addressing making OpenCV an optional dependency else: npts = len(pt) a = np.zeros((4, 4)) coords = np.empty((npts, 4)) coords[:] = 1 for i in range(npts): # Compute AX = 0 a[0] = pt[i][0] * p[2] - p[0] a[1] = pt[i][1] * p[2] - p[1] a[2] = pt1[i][0] * p1[2] - p1[0] a[3] = pt1[i][1] * p1[2] - p1[1] # v.T is a least squares solution that minimizes the error residual u, s, vh = np.linalg.svd(a) v = vh.T coords[i] = v[:,3] / (v[:,3][-1]) return coords.T """ def projection_error(p1, p, pt, pt1): """ Based on Hartley and Zisserman p.285 this function triangulates image correspondences and computes the reprojection error by back-projecting the points into the image. References ---------- .. [Hartley2003] This is the classic cost function (minimization problem) into the gold standard method for fundamental matrix estimation. Parameters ----------- Loading @@ -137,29 +151,25 @@ def projection_error(p1, p, pt, pt1): Returns ------- residuals : ndarray (n, 1) residuals for each correspondence cumulative_error : float sum of the residuals reproj_error : ndarray (n, 1) vector of reprojection errors """ # SciPy least squares solver needs a vector, so reshape back to a 3x4 c # camera matrix at each iteration if p1.shape != (3,4): p1 = p1.reshape(3,4) # Triangulate the correspondences xw_est = triangulate(pt, pt1, p, p1) # Back project and homogenize xhat = np.dot(p, xw_est) xhat /= xhat[2] x2hat = np.dot(p1, xw_est) x2hat /= x2hat[2] xhat = triangulate(pt, pt1, p, p1) xhat1 = xhat[:3] / xhat[2] xhat2 = p1.dot(xhat) xhat2 /= xhat2[2] # Compute residuals dist = (pt.T - xhat)**2 + (pt1.T - x2hat)**2 residuals = np.sum(dist, axis=0) reproj_error = np.sum(dist) # Compute error cost = (pt - xhat1)**2 + (pt1 - xhat2)**2 cost = np.sqrt(np.sum(cost, axis=0)) return residuals, reproj_error return cost