Commit e13d668a authored by Jay's avatar Jay Committed by Jason R Laura
Browse files

Standardize the interface to the feature extractor

parent ba7af8eb
Loading
Loading
Loading
Loading
+1 −23
Changes for autocnet/graph/node.py: 1 added line, 23 removed lines.
Original line number Diff line number Diff line
@@ -226,29 +226,7 @@ class Node(dict, MutableMapping):
                 kwargs passed to autocnet.feature_extractor.extract_features

        """
        keypoint_objs, self.descriptors = fe.extract_features(array, **kwargs)
        if self.descriptors.dtype != np.float32:
            self.descriptors = self.descriptors.astype(np.float32)

        # OpenCV returned keypoint objects
        if isinstance(keypoint_objs, list):
            keypoints = np.empty((len(keypoint_objs), 7), dtype=np.float32)
            for i, kpt in enumerate(keypoint_objs):
                octave = kpt.octave & 8
                layer = (kpt.octave >> 8) & 255
                if octave < 128:
                    octave = octave
                else:
                    octave = (-128 | octave)
                keypoints[i] = kpt.pt[0], kpt.pt[1], kpt.response, kpt.size, kpt.angle, octave, layer  # y, x
            self._keypoints = pd.DataFrame(keypoints, columns=['x', 'y', 'response', 'size',
                                                               'angle', 'octave', 'layer'])

        # VLFeat returned keypoint objects
        elif isinstance(keypoint_objs, np.ndarray):
            # Swap columns for value style access, vl_feat returns y, x
            keypoint_objs[:, 0], keypoint_objs[:, 1] = keypoint_objs[:, 1], keypoint_objs[:, 0].copy()
            self._keypoints = pd.DataFrame(keypoint_objs, columns=['x', 'y', 'size', 'angle'])
        self._keypoints, self.descriptors = fe.extract_features(array, **kwargs)

    def load_features(self, in_path):
        """
+33 −4
Changes for autocnet/matcher/feature_extractor.py: 33 added lines, 4 removed lines.
Original line number Diff line number Diff line
import cv2
import numpy as np
import pandas as pd

from scipy.misc import bytescale

@@ -30,8 +32,11 @@ def extract_features(array, method='orb', extractor_parameters={}):

    Returns
    -------
    : tuple
      in the form ([list of OpenCV KeyPoints], [NumPy array of descriptors as geometric vectors])
    keypoints : DataFrame
                data frame of coordinates ('x', 'y', 'size', 'angle', and other available information)

    descriptors : ndarray
                  Of descriptors
    """

    detectors = {'fast': cv2.FastFeatureDetector_create,
@@ -42,10 +47,34 @@ def extract_features(array, method='orb', extractor_parameters={}):
        detectors['vl_sift'] = vl.sift.sift

    if 'vl_' in method:
        return detectors[method](array, compute_descriptor=True, float_descriptors=True, **extractor_parameters)
        keypoint_objs, descriptors = detectors[method](array,
                                                       compute_descriptor=True,
                                                       float_descriptors=True,
                                                       **extractor_parameters)
        # Swap columns for value style access, vl_feat returns y, x
        keypoint_objs[:, 0], keypoint_objs[:, 1] = keypoint_objs[:, 1], keypoint_objs[:, 0].copy()
        keypoints = pd.DataFrame(keypoint_objs, columns=['x', 'y', 'size', 'angle'])

    else:
        # OpenCV requires the input images to be 8-bit
        if not array.dtype == 'int8':
            array = bytescale(array)
        detector = detectors[method](**extractor_parameters)
        return detector.detectAndCompute(array, None)
        keypoint_objs, descriptors = detector.detectAndCompute(array, None)

        keypoints = np.empty((len(keypoint_objs), 7), dtype=np.float32)
        for i, kpt in enumerate(keypoint_objs):
            octave = kpt.octave & 8
            layer = (kpt.octave >> 8) & 255
            if octave < 128:
                octave = octave
            else:
                octave = (-128 | octave)
            keypoints[i] = kpt.pt[0], kpt.pt[1], kpt.response, kpt.size, kpt.angle, octave, layer  # y, x
        keypoints = pd.DataFrame(keypoints, columns=['x', 'y', 'response', 'size',
                                                     'angle', 'octave', 'layer'])

        if descriptors.dtype != np.float32:
            descriptors = descriptors.astype(np.float32)

    return keypoints, descriptors
 No newline at end of file
+4 −6
Changes for autocnet/matcher/tests/test_feature_extractor.py: 4 added lines, 6 removed lines.
Original line number Diff line number Diff line
import os
import numpy as np
import pandas as pd
import unittest
from autocnet.examples import get_path
import cv2
@@ -25,17 +26,14 @@ class TestFeatureExtractor(unittest.TestCase):
                          "sigma": 1.6}

    def test_extract_features(self):
        features = feature_extractor.extract_features(self.data_array,
        features, descriptors = feature_extractor.extract_features(self.data_array,
                                                                   method='sift',
                                                                   extractor_parameters=self.parameters)
        self.assertEquals(len(features), 2)
        self.assertIn(len(features[0]), range(8, 12))
        self.assertIsInstance(features[0][0], type(cv2.KeyPoint()))
        self.assertIsInstance(features[1][0], np.ndarray)
        self.assertEquals(len(features), 10)

    def test_extract_vlfeat(self):
        kps, descriptors = feature_extractor.extract_features(self.data_array,
                                                              method='vl_sift',
                                                              extractor_parameters={})
        self.assertIsInstance(kps, np.ndarray)
        self.assertIsInstance(kps, pd.DataFrame)
        self.assertEqual(descriptors.dtype, np.float32)