From ad85dfabd57f55c8cabef5dbfe7e757f96ec677b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Thu, 22 Jan 2015 06:49:16 -0500 Subject: [PATCH] Disable catch of all warnings, return nan params instead --- skimage/measure/fit.py | 15 +--- skimage/measure/tests/test_fit.py | 20 ----- skimage/transform/_geometric.py | 16 +++- skimage/transform/tests/test_geometric.py | 98 +++++++++++++---------- 4 files changed, 71 insertions(+), 78 deletions(-) diff --git a/skimage/measure/fit.py b/skimage/measure/fit.py index e800eb89..7de90291 100644 --- a/skimage/measure/fit.py +++ b/skimage/measure/fit.py @@ -502,7 +502,7 @@ def _dynamic_max_trials(n_inliers, n_samples, min_samples, probability): def ransac(data, model_class, min_samples, residual_threshold, is_data_valid=None, is_model_valid=None, max_trials=100, stop_sample_num=np.inf, stop_residuals_sum=0, - stop_probability=1, exceptions=Exception): + stop_probability=1): """Fit a model to data with the RANSAC (random sample consensus) algorithm. RANSAC is an iterative algorithm for the robust estimation of parameters @@ -573,10 +573,6 @@ def ransac(data, model_class, min_samples, residual_threshold, where the probability (confidence) is typically set to a high value such as 0.99, and e is the current fraction of inliers w.r.t. the total number of samples. - exceptions : exception class or tuple of exception classes - A list of exceptions that are ignored when estimating the model from a - random subset. By default all exceptions derived from the built-in - exception class `Exception` are ignored. Returns ------- @@ -692,14 +688,7 @@ def ransac(data, model_class, min_samples, residual_threshold, # estimate model for current random sample set sample_model = model_class() - - if exceptions: - try: - sample_model.estimate(*samples) - except exceptions: - continue - else: - sample_model.estimate(*samples) + sample_model.estimate(*samples) # check if estimated model is valid if is_model_valid is not None and not is_model_valid(sample_model, diff --git a/skimage/measure/tests/test_fit.py b/skimage/measure/tests/test_fit.py index c8e789fb..1b960d4b 100644 --- a/skimage/measure/tests/test_fit.py +++ b/skimage/measure/tests/test_fit.py @@ -247,26 +247,6 @@ def test_ransac_invalid_input(): residual_threshold=0, stop_probability=1.01) -def test_ransac_exceptions(): - class Estimator(object): - def estimate(self, x): - raise AttributeError - - def residuals(self, x): - return x - - assert_raises(AttributeError, ransac, (np.zeros((10,)),), Estimator, - min_samples=2, residual_threshold=0, exceptions=None) - assert_raises(AttributeError, ransac, (np.zeros((10,)),), Estimator, - min_samples=2, residual_threshold=0, exceptions=tuple()) - - ransac((np.zeros((10,)),), Estimator, min_samples=2, residual_threshold=0) - ransac((np.zeros((10,)),), Estimator, min_samples=2, - residual_threshold=0, exceptions=AttributeError) - ransac((np.zeros((10,)),), Estimator, min_samples=2, - residual_threshold=0, exceptions=(AttributeError,)) - - def test_deprecated_params_attribute(): model = LineModel() model.params = (10, 1) diff --git a/skimage/transform/_geometric.py b/skimage/transform/_geometric.py index 22a09980..f3c56d7a 100644 --- a/skimage/transform/_geometric.py +++ b/skimage/transform/_geometric.py @@ -265,8 +265,12 @@ class ProjectiveTransform(GeometricTransform): """ - src_matrix, src = _center_and_normalize_points(src) - dst_matrix, dst = _center_and_normalize_points(dst) + try: + src_matrix, src = _center_and_normalize_points(src) + dst_matrix, dst = _center_and_normalize_points(dst) + except ZeroDivisionError: + self.params = np.nan * np.empty((3, 3)) + return xs = src[:, 0] ys = src[:, 1] @@ -652,8 +656,12 @@ class SimilarityTransform(ProjectiveTransform): """ - src_matrix, src = _center_and_normalize_points(src) - dst_matrix, dst = _center_and_normalize_points(dst) + try: + src_matrix, src = _center_and_normalize_points(src) + dst_matrix, dst = _center_and_normalize_points(dst) + except ZeroDivisionError: + self.params = np.nan * np.empty((3, 3)) + return xs = src[:, 0] ys = src[:, 1] diff --git a/skimage/transform/tests/test_geometric.py b/skimage/transform/tests/test_geometric.py index 125faf6c..d34e5e8f 100644 --- a/skimage/transform/tests/test_geometric.py +++ b/skimage/transform/tests/test_geometric.py @@ -1,5 +1,5 @@ import numpy as np -from numpy.testing import (assert_equal, assert_array_almost_equal, +from numpy.testing import (assert_equal, assert_almost_equal, assert_raises) from skimage.transform._geometric import _stackcopy from skimage.transform._geometric import GeometricTransform @@ -38,7 +38,7 @@ def test_stackcopy(): y = np.eye(3, 3) _stackcopy(x, y) for i in range(layers): - assert_array_almost_equal(x[..., i], y) + assert_almost_equal(x[..., i], y) def test_estimate_transform(): @@ -56,20 +56,20 @@ def test_matrix_transform(): def test_similarity_estimation(): # exact solution tform = estimate_transform('similarity', SRC[:2, :], DST[:2, :]) - assert_array_almost_equal(tform(SRC[:2, :]), DST[:2, :]) + assert_almost_equal(tform(SRC[:2, :]), DST[:2, :]) assert_equal(tform.params[0, 0], tform.params[1, 1]) assert_equal(tform.params[0, 1], - tform.params[1, 0]) # over-determined tform2 = estimate_transform('similarity', SRC, DST) - assert_array_almost_equal(tform2.inverse(tform2(SRC)), SRC) + assert_almost_equal(tform2.inverse(tform2(SRC)), SRC) assert_equal(tform2.params[0, 0], tform2.params[1, 1]) assert_equal(tform2.params[0, 1], - tform2.params[1, 0]) # via estimate method tform3 = SimilarityTransform() tform3.estimate(SRC, DST) - assert_array_almost_equal(tform3.params, tform2.params) + assert_almost_equal(tform3.params, tform2.params) def test_similarity_init(): @@ -79,15 +79,15 @@ def test_similarity_init(): translation = (1, 1) tform = SimilarityTransform(scale=scale, rotation=rotation, translation=translation) - assert_array_almost_equal(tform.scale, scale) - assert_array_almost_equal(tform.rotation, rotation) - assert_array_almost_equal(tform.translation, translation) + assert_almost_equal(tform.scale, scale) + assert_almost_equal(tform.rotation, rotation) + assert_almost_equal(tform.translation, translation) # init with transformation matrix tform2 = SimilarityTransform(tform.params) - assert_array_almost_equal(tform2.scale, scale) - assert_array_almost_equal(tform2.rotation, rotation) - assert_array_almost_equal(tform2.translation, translation) + assert_almost_equal(tform2.scale, scale) + assert_almost_equal(tform2.rotation, rotation) + assert_almost_equal(tform2.translation, translation) # test special case for scale if rotation=0 scale = 0.1 @@ -95,9 +95,9 @@ def test_similarity_init(): translation = (1, 1) tform = SimilarityTransform(scale=scale, rotation=rotation, translation=translation) - assert_array_almost_equal(tform.scale, scale) - assert_array_almost_equal(tform.rotation, rotation) - assert_array_almost_equal(tform.translation, translation) + assert_almost_equal(tform.scale, scale) + assert_almost_equal(tform.rotation, rotation) + assert_almost_equal(tform.translation, translation) # test special case for scale if rotation=90deg @@ -106,24 +106,24 @@ def test_similarity_init(): translation = (1, 1) tform = SimilarityTransform(scale=scale, rotation=rotation, translation=translation) - assert_array_almost_equal(tform.scale, scale) - assert_array_almost_equal(tform.rotation, rotation) - assert_array_almost_equal(tform.translation, translation) + assert_almost_equal(tform.scale, scale) + assert_almost_equal(tform.rotation, rotation) + assert_almost_equal(tform.translation, translation) def test_affine_estimation(): # exact solution tform = estimate_transform('affine', SRC[:3, :], DST[:3, :]) - assert_array_almost_equal(tform(SRC[:3, :]), DST[:3, :]) + assert_almost_equal(tform(SRC[:3, :]), DST[:3, :]) # over-determined tform2 = estimate_transform('affine', SRC, DST) - assert_array_almost_equal(tform2.inverse(tform2(SRC)), SRC) + assert_almost_equal(tform2.inverse(tform2(SRC)), SRC) # via estimate method tform3 = AffineTransform() tform3.estimate(SRC, DST) - assert_array_almost_equal(tform3.params, tform2.params) + assert_almost_equal(tform3.params, tform2.params) def test_affine_init(): @@ -134,71 +134,71 @@ def test_affine_init(): translation = (1, 1) tform = AffineTransform(scale=scale, rotation=rotation, shear=shear, translation=translation) - assert_array_almost_equal(tform.scale, scale) - assert_array_almost_equal(tform.rotation, rotation) - assert_array_almost_equal(tform.shear, shear) - assert_array_almost_equal(tform.translation, translation) + assert_almost_equal(tform.scale, scale) + assert_almost_equal(tform.rotation, rotation) + assert_almost_equal(tform.shear, shear) + assert_almost_equal(tform.translation, translation) # init with transformation matrix tform2 = AffineTransform(tform.params) - assert_array_almost_equal(tform2.scale, scale) - assert_array_almost_equal(tform2.rotation, rotation) - assert_array_almost_equal(tform2.shear, shear) - assert_array_almost_equal(tform2.translation, translation) + assert_almost_equal(tform2.scale, scale) + assert_almost_equal(tform2.rotation, rotation) + assert_almost_equal(tform2.shear, shear) + assert_almost_equal(tform2.translation, translation) def test_piecewise_affine(): tform = PiecewiseAffineTransform() tform.estimate(SRC, DST) # make sure each single affine transform is exactly estimated - assert_array_almost_equal(tform(SRC), DST) - assert_array_almost_equal(tform.inverse(DST), SRC) + assert_almost_equal(tform(SRC), DST) + assert_almost_equal(tform.inverse(DST), SRC) def test_projective_estimation(): # exact solution tform = estimate_transform('projective', SRC[:4, :], DST[:4, :]) - assert_array_almost_equal(tform(SRC[:4, :]), DST[:4, :]) + assert_almost_equal(tform(SRC[:4, :]), DST[:4, :]) # over-determined tform2 = estimate_transform('projective', SRC, DST) - assert_array_almost_equal(tform2.inverse(tform2(SRC)), SRC) + assert_almost_equal(tform2.inverse(tform2(SRC)), SRC) # via estimate method tform3 = ProjectiveTransform() tform3.estimate(SRC, DST) - assert_array_almost_equal(tform3.params, tform2.params) + assert_almost_equal(tform3.params, tform2.params) def test_projective_init(): tform = estimate_transform('projective', SRC, DST) # init with transformation matrix tform2 = ProjectiveTransform(tform.params) - assert_array_almost_equal(tform2.params, tform.params) + assert_almost_equal(tform2.params, tform.params) def test_polynomial_estimation(): # over-determined tform = estimate_transform('polynomial', SRC, DST, order=10) - assert_array_almost_equal(tform(SRC), DST, 6) + assert_almost_equal(tform(SRC), DST, 6) # via estimate method tform2 = PolynomialTransform() tform2.estimate(SRC, DST, order=10) - assert_array_almost_equal(tform2.params, tform.params) + assert_almost_equal(tform2.params, tform.params) def test_polynomial_init(): tform = estimate_transform('polynomial', SRC, DST, order=10) # init with transformation parameters tform2 = PolynomialTransform(tform.params) - assert_array_almost_equal(tform2.params, tform.params) + assert_almost_equal(tform2.params, tform.params) def test_polynomial_default_order(): tform = estimate_transform('polynomial', SRC, DST) tform2 = estimate_transform('polynomial', SRC, DST, order=2) - assert_array_almost_equal(tform2.params, tform.params) + assert_almost_equal(tform2.params, tform.params) def test_polynomial_inverse(): @@ -210,17 +210,17 @@ def test_union(): tform2 = SimilarityTransform(scale=0.1, rotation=0.9) tform3 = SimilarityTransform(scale=0.1 ** 2, rotation=0.3 + 0.9) tform = tform1 + tform2 - assert_array_almost_equal(tform.params, tform3.params) + assert_almost_equal(tform.params, tform3.params) tform1 = AffineTransform(scale=(0.1, 0.1), rotation=0.3) tform2 = SimilarityTransform(scale=0.1, rotation=0.9) tform3 = SimilarityTransform(scale=0.1 ** 2, rotation=0.3 + 0.9) tform = tform1 + tform2 - assert_array_almost_equal(tform.params, tform3.params) + assert_almost_equal(tform.params, tform3.params) assert tform.__class__ == ProjectiveTransform tform = AffineTransform(scale=(0.1, 0.1), rotation=0.3) - assert_array_almost_equal((tform + tform.inverse).params, np.eye(3)) + assert_almost_equal((tform + tform.inverse).params, np.eye(3)) def test_union_differing_types(): @@ -260,6 +260,22 @@ def test_deprecated_params_attributes(): assert_equal(tform._params, tform.params) +def test_degenerate(): + src = dst = np.zeros((10, 2)) + + tform = SimilarityTransform() + tform.estimate(src, dst) + assert np.all(np.isnan(tform.params)) + + tform = AffineTransform() + tform.estimate(src, dst) + assert np.all(np.isnan(tform.params)) + + tform = ProjectiveTransform() + tform.estimate(src, dst) + assert np.all(np.isnan(tform.params)) + + if __name__ == "__main__": from numpy.testing import run_module_suite run_module_suite()