Loading autocnet/matcher/tests/test_outlier_detector.py +1 −1 Original line number Diff line number Diff line Loading @@ -78,7 +78,7 @@ class TestSpatialSuppression(unittest.TestCase): self.suppression_obj.error_k = 0.05 self.assertEqual(self.suppression_obj.error_k, 0.05) self.assertEqual(self.suppression_obj.nvalid, None) self.assertEqual(self.suppression_obj.nvalid, 0) self.assertIsInstance(self.suppression_obj.df, pd.DataFrame) def test_suppress_non_optimal(self): Loading autocnet/transformation/tests/test_transformations.py +4 −17 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ class TestHomography(unittest.TestCase): h = transformations.Homography(np.arange(4).reshape(2,2), np.arange(3), np.arange(3), None) class TestFundamentalMatrix(unittest.TestCase): def test_FundamentalMatrix(self): Loading @@ -61,24 +62,10 @@ class TestFundamentalMatrix(unittest.TestCase): tp /= tp[-1, :np.newaxis] F = transformations.FundamentalMatrix(static_F, pd.DataFrame(fp, columns=['x', 'y']), pd.DataFrame(tp.T[:, :2], columns=['x', 'y']), pd.DataFrame(fph, columns=['x', 'y', 'h']), pd.DataFrame(tp.T, columns=['x', 'y', 'h']), mask=pd.Series(True, index=np.arange(fp.shape[0]))) self.assertAlmostEqual(F.determinant, 0.624999, 5) self.assertIsInstance(F.error, pd.Series) self.assertIsInstance(F.error, pd.DataFrame) # This should raise an error. F.refine() self.assertIsInstance(F.error, pd.DataFrame) self.assertEqual(len(F._action_stack), 1) # Previous error should preclude do/undo F.rollback() self.assertEqual(F._current_action_stack, 0) F.rollforward() self.assertEqual(F._current_action_stack, 0) F._clean_attrs() self.assertNotIn('_error', F.__dict__) autocnet/transformation/transformations.py +6 −77 Original line number Diff line number Diff line Loading @@ -175,71 +175,8 @@ class FundamentalMatrix(TransformationMatrix): compute this homography """ def refine(self, method=ps.esda.mapclassify.Fisher_Jenks, df=None, bin_id=0, **kwargs): """ Refine the fundamental matrix by accepting some data classification method that accepts an ndarray and returns an object with a bins attribute, where bins are data breaks. Using the bin_id, mask all values greater than the selected bin. Then compute a new fundamental matrix. The matrix is "refined" based on the reprojection errors for each point. Parameters ---------- method : object A function that accepts and ndarray and returns an object with a bins attribute df : dataframe Dataframe (from which a ndarray will be extracted) to pass to the method. bin_id : int The index into the bins object. Data classified > this id is masked kwargs : dict Keyword args supported by the data classifier Returns ------- FundamentalMatrix : object A fundamental matrix class object mask : series A bool mask with index attribute identifying the valid data in the new fundamental matrix. """ # Perform the data classification if df is None: df = self.error fj = method(df.values.ravel(), **kwargs) bins = fj.bins # Mask the data that falls outside the provided bins mask = df.iloc[:, 0] <= bins[bin_id] new_x1 = self.x1.iloc[mask[mask == True].index] new_x2 = self.x2.iloc[mask[mask == True].index] fmatrix, new_mask = compute_fundamental_matrix(new_x1.values, new_x2.values) mask[mask == True] = new_mask # Update the current state self[:] = fmatrix self.mask = mask # Update the action stack try: state_package = {'arr': fmatrix.copy(), 'mask': self.mask.copy()} self._action_stack.append(state_package) self._current_action_stack = len(self._action_stack) - 1 # 0 based vs. 1 based self._clean_attrs() self._notify_subscribers(self) except: warnings.warn('Refinement outlier detection removed all observations.', UserWarning) def refine(self): pass def _clean_attrs(self): for a in ['_error', '_determinant', '_condition']: Loading Loading @@ -289,24 +226,16 @@ class FundamentalMatrix(TransformationMatrix): x1 : dataframe n,3 dataframe of homogeneous coordinates with the same length as argument a mask : Series Index to be used in the returned dataframe length as argument x Returns ------- df : dataframe With columns for x_residual, y_residual, rmse, and error contribution. The dataframe also has cumulative x, t, and total RMS statistics accessible via df.x_rms, df.y_rms, and df.total_rms, respectively. F_error : ndarray n,1 vector of reprojection errors """ # Normalize the vector l_norms = normalize_vector(x.dot(self.T)) F_error = np.abs(np.sum(l_norms * x1, axis=1)) return F_error Loading autocnet/utils/tests/test_utils.py +2 −2 Original line number Diff line number Diff line Loading @@ -106,7 +106,7 @@ class TestUtils(unittest.TestCase): 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) x = np.repeat(np.arange(1,5), 3).reshape(-1, 3) y = utils.normalize_vector(x) truth = np.tile(np.array([ 0.70710678, 0.70710678, 0.70710678]), 4) truth = np.tile(np.array([ 0.70710678, 0.70710678, 0.70710678]), 4).reshape(4,3) np.testing.assert_array_almost_equal(truth, y) autocnet/utils/utils.py +2 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,8 @@ def normalize_vector(line): n = np.sqrt(line[:, 0]**2 + line[:, 1]**2).reshape(-1, 1) except: n = np.sqrt(line[0]**2 + line[1]**2) line /= n print(line, n) line = line / n return line Loading Loading
autocnet/matcher/tests/test_outlier_detector.py +1 −1 Original line number Diff line number Diff line Loading @@ -78,7 +78,7 @@ class TestSpatialSuppression(unittest.TestCase): self.suppression_obj.error_k = 0.05 self.assertEqual(self.suppression_obj.error_k, 0.05) self.assertEqual(self.suppression_obj.nvalid, None) self.assertEqual(self.suppression_obj.nvalid, 0) self.assertIsInstance(self.suppression_obj.df, pd.DataFrame) def test_suppress_non_optimal(self): Loading
autocnet/transformation/tests/test_transformations.py +4 −17 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ class TestHomography(unittest.TestCase): h = transformations.Homography(np.arange(4).reshape(2,2), np.arange(3), np.arange(3), None) class TestFundamentalMatrix(unittest.TestCase): def test_FundamentalMatrix(self): Loading @@ -61,24 +62,10 @@ class TestFundamentalMatrix(unittest.TestCase): tp /= tp[-1, :np.newaxis] F = transformations.FundamentalMatrix(static_F, pd.DataFrame(fp, columns=['x', 'y']), pd.DataFrame(tp.T[:, :2], columns=['x', 'y']), pd.DataFrame(fph, columns=['x', 'y', 'h']), pd.DataFrame(tp.T, columns=['x', 'y', 'h']), mask=pd.Series(True, index=np.arange(fp.shape[0]))) self.assertAlmostEqual(F.determinant, 0.624999, 5) self.assertIsInstance(F.error, pd.Series) self.assertIsInstance(F.error, pd.DataFrame) # This should raise an error. F.refine() self.assertIsInstance(F.error, pd.DataFrame) self.assertEqual(len(F._action_stack), 1) # Previous error should preclude do/undo F.rollback() self.assertEqual(F._current_action_stack, 0) F.rollforward() self.assertEqual(F._current_action_stack, 0) F._clean_attrs() self.assertNotIn('_error', F.__dict__)
autocnet/transformation/transformations.py +6 −77 Original line number Diff line number Diff line Loading @@ -175,71 +175,8 @@ class FundamentalMatrix(TransformationMatrix): compute this homography """ def refine(self, method=ps.esda.mapclassify.Fisher_Jenks, df=None, bin_id=0, **kwargs): """ Refine the fundamental matrix by accepting some data classification method that accepts an ndarray and returns an object with a bins attribute, where bins are data breaks. Using the bin_id, mask all values greater than the selected bin. Then compute a new fundamental matrix. The matrix is "refined" based on the reprojection errors for each point. Parameters ---------- method : object A function that accepts and ndarray and returns an object with a bins attribute df : dataframe Dataframe (from which a ndarray will be extracted) to pass to the method. bin_id : int The index into the bins object. Data classified > this id is masked kwargs : dict Keyword args supported by the data classifier Returns ------- FundamentalMatrix : object A fundamental matrix class object mask : series A bool mask with index attribute identifying the valid data in the new fundamental matrix. """ # Perform the data classification if df is None: df = self.error fj = method(df.values.ravel(), **kwargs) bins = fj.bins # Mask the data that falls outside the provided bins mask = df.iloc[:, 0] <= bins[bin_id] new_x1 = self.x1.iloc[mask[mask == True].index] new_x2 = self.x2.iloc[mask[mask == True].index] fmatrix, new_mask = compute_fundamental_matrix(new_x1.values, new_x2.values) mask[mask == True] = new_mask # Update the current state self[:] = fmatrix self.mask = mask # Update the action stack try: state_package = {'arr': fmatrix.copy(), 'mask': self.mask.copy()} self._action_stack.append(state_package) self._current_action_stack = len(self._action_stack) - 1 # 0 based vs. 1 based self._clean_attrs() self._notify_subscribers(self) except: warnings.warn('Refinement outlier detection removed all observations.', UserWarning) def refine(self): pass def _clean_attrs(self): for a in ['_error', '_determinant', '_condition']: Loading Loading @@ -289,24 +226,16 @@ class FundamentalMatrix(TransformationMatrix): x1 : dataframe n,3 dataframe of homogeneous coordinates with the same length as argument a mask : Series Index to be used in the returned dataframe length as argument x Returns ------- df : dataframe With columns for x_residual, y_residual, rmse, and error contribution. The dataframe also has cumulative x, t, and total RMS statistics accessible via df.x_rms, df.y_rms, and df.total_rms, respectively. F_error : ndarray n,1 vector of reprojection errors """ # Normalize the vector l_norms = normalize_vector(x.dot(self.T)) F_error = np.abs(np.sum(l_norms * x1, axis=1)) return F_error Loading
autocnet/utils/tests/test_utils.py +2 −2 Original line number Diff line number Diff line Loading @@ -106,7 +106,7 @@ class TestUtils(unittest.TestCase): 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) x = np.repeat(np.arange(1,5), 3).reshape(-1, 3) y = utils.normalize_vector(x) truth = np.tile(np.array([ 0.70710678, 0.70710678, 0.70710678]), 4) truth = np.tile(np.array([ 0.70710678, 0.70710678, 0.70710678]), 4).reshape(4,3) np.testing.assert_array_almost_equal(truth, y)
autocnet/utils/utils.py +2 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,8 @@ def normalize_vector(line): n = np.sqrt(line[:, 0]**2 + line[:, 1]**2).reshape(-1, 1) except: n = np.sqrt(line[0]**2 + line[1]**2) line /= n print(line, n) line = line / n return line Loading