From 01124f5bcc75e07c3f7e13b0aefc8942ada2f76d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Mon, 6 May 2013 18:08:21 +0200 Subject: [PATCH] Use boolean mask for inlier return value of RANSAC --- doc/examples/plot_matching.py | 16 ++++++---------- skimage/measure/fit.py | 9 +++------ skimage/measure/tests/test_fit.py | 11 +++++------ 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/doc/examples/plot_matching.py b/doc/examples/plot_matching.py index 57919080..d01231fe 100644 --- a/doc/examples/plot_matching.py +++ b/doc/examples/plot_matching.py @@ -105,6 +105,7 @@ model.estimate(src, dst) # robustly estimate affine transform model with RANSAC model_robust, inliers = ransac((src, dst), AffineTransform, min_samples=3, residual_threshold=2, max_trials=100) +outliers = inliers == False # compare "true" and estimated transform parameters @@ -128,16 +129,11 @@ ax[1].axis('off') ax[1].axis((0, 400, 200, 0)) ax[1].set_title('Faulty correspondencies') -for i in range(len(src)): - if i in inliers: - ax_idx = 0 - color = 'g' - else: - ax_idx = 1 - color = 'r' - ax[ax_idx].plot((src[i, 1], dst[i, 1] + 200), (src[i, 0], dst[i, 0]), '-', + +for ax_idx, (m, color) in enumerate(((inliers, 'g'), (outliers, 'r'))): + ax[ax_idx].plot((src[m, 1], dst[m, 1] + 200), (src[m, 0], dst[m, 0]), '-', color=color) - ax[ax_idx].plot(src[i, 1], src[i, 0], '.', markersize=10, color=color) - ax[ax_idx].plot(dst[i, 1] + 200, dst[i, 0], '.', markersize=10, color=color) + ax[ax_idx].plot(src[m, 1], src[m, 0], '.', markersize=10, color=color) + ax[ax_idx].plot(dst[m, 1] + 200, dst[m, 0], '.', markersize=10, color=color) plt.show() diff --git a/skimage/measure/fit.py b/skimage/measure/fit.py index fa78fb82..87febf70 100644 --- a/skimage/measure/fit.py +++ b/skimage/measure/fit.py @@ -517,7 +517,7 @@ def ransac(data, model_class, min_samples, residual_threshold, model : object Best model with largest consensus set. inliers : (N, ) array - Indices of inliers. + Boolean mask of inliers classified as ``True``. References ---------- @@ -598,8 +598,6 @@ def ransac(data, model_class, min_samples, residual_threshold, # number of samples N = data[0].shape[0] - data_idxs = np.arange(N) - for _ in range(max_trials): # choose random sample set @@ -623,12 +621,11 @@ def ransac(data, model_class, min_samples, residual_threshold, sample_model_residuals = np.abs(sample_model.residuals(*data)) # consensus set / inliers - sample_model_inliers = data_idxs[sample_model_residuals - < residual_threshold] + sample_model_inliers = sample_model_residuals < residual_threshold sample_model_residuals_sum = np.sum(sample_model_residuals**2) # choose as new best model if number of inliers is maximal - sample_inlier_num = sample_model_inliers.shape[0] + sample_inlier_num = np.sum(sample_model_inliers) if ( # more inliers sample_inlier_num > best_inlier_num diff --git a/skimage/measure/tests/test_fit.py b/skimage/measure/tests/test_fit.py index 0f21b49b..a2a40f58 100644 --- a/skimage/measure/tests/test_fit.py +++ b/skimage/measure/tests/test_fit.py @@ -167,17 +167,16 @@ def test_ransac_geometric(): # add some faulty data outliers = (0, 5, 20) - dst[0] = (10000, 10000) - dst[1] = (-100, 100) - dst[2] = (50, 50) + dst[outliers[0]] = (10000, 10000) + dst[outliers[1]] = (-100, 100) + dst[outliers[2]] = (50, 50) # estimate parameters of corrupted data - model_est, inliers = ransac((src, dst), AffineTransform, 2, 10) + model_est, inliers = ransac((src, dst), AffineTransform, 2, 20) # test whether estimated parameters equal original parameters assert_almost_equal(model0._matrix, model_est._matrix) - for outlier in outliers: - assert outlier not in inliers + assert np.all(np.nonzero(inliers == False)[0] == outliers) def test_ransac_is_data_valid():