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, random_state=None, initial_inliers=None): best_model = None best_inlier_num = 0 best_inlier_residuals_sum = np.inf best_inliers = None random_state = check_random_state(random_state) num_samples = len(data[0]) for num_trials in range(max_trials): # choose random sample spl_idxs = random_state.choice(num_samples, min_samples, replace=False) samples = [d[spl_idxs] for d in data] sample_model = model_class() success = sample_model.estimate(samples) sample_model_residuals = np.abs(sample_model.residuals(data)) sample_model_residuals_sum = np.sum(sample_model_residuals**2) sample_model_inliers = sample_model_residuals < residual_threshold sample_inlier_num = np.sum(sample_model_inliers) if (sample_inlier_num > best_inlier_num or (sample_inlier_num == best_inlier_num and sample_model_residuals_sum < best_inlier_residuals_sum)): best_model = sample_model best_inlier_num = sample_inlier_num best_inlier_residuals_sum = sample_model_residuals_sum best_inliers = sample_model_inliers dynamic_max_trials = _dynamic_max_trials(best_inlier_num, num_samples, min_samples, stop_probability) if (best_inlier_num >= stop_sample_num or best_inlier_residuals_sum <= stop_residuals_sum or num_trials >= dynamic_max_trials): break # estimate final model using all inliers if best_inliers is not None: # select inliers for each data array data_inliers = [d[best_inliers] for d in data] best_model.estimate(data_inliers) return best_model, best_inliers
def test_ransac_dynamic_max_trials(): # Numbers hand-calculated and confirmed on page 119 (Table 4.3) in # Hartley, R.~I. and Zisserman, A., 2004, # Multiple View Geometry in Computer Vision, Second Edition, # Cambridge University Press, ISBN: 0521540518 # e = 0%, min_samples = X assert_equal(_dynamic_max_trials(100, 100, 2, 0.99), 1) # e = 5%, min_samples = 2 assert_equal(_dynamic_max_trials(95, 100, 2, 0.99), 2) # e = 10%, min_samples = 2 assert_equal(_dynamic_max_trials(90, 100, 2, 0.99), 3) # e = 30%, min_samples = 2 assert_equal(_dynamic_max_trials(70, 100, 2, 0.99), 7) # e = 50%, min_samples = 2 assert_equal(_dynamic_max_trials(50, 100, 2, 0.99), 17) # e = 5%, min_samples = 8 assert_equal(_dynamic_max_trials(95, 100, 8, 0.99), 5) # e = 10%, min_samples = 8 assert_equal(_dynamic_max_trials(90, 100, 8, 0.99), 9) # e = 30%, min_samples = 8 assert_equal(_dynamic_max_trials(70, 100, 8, 0.99), 78) # e = 50%, min_samples = 8 assert_equal(_dynamic_max_trials(50, 100, 8, 0.99), 1177) # e = 0%, min_samples = 5 assert_equal(_dynamic_max_trials(1, 100, 5, 0), 0) assert_equal(_dynamic_max_trials(1, 100, 5, 1), np.inf)