mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-15 11:25:53 +08:00
allowing to pass a np.random.RandomState to ransac
This commit is contained in:
+28
-2
@@ -1,4 +1,5 @@
|
||||
import math
|
||||
import numbers
|
||||
import numpy as np
|
||||
from scipy import optimize
|
||||
from .._shared.utils import skimage_deprecation, warn
|
||||
@@ -687,12 +688,29 @@ def _dynamic_max_trials(n_inliers, n_samples, min_samples, probability):
|
||||
return 0
|
||||
|
||||
return int(np.ceil(nom / denom))
|
||||
|
||||
|
||||
def check_random_state(seed):
|
||||
"""Turn seed into a np.random.RandomState instance
|
||||
If seed is None, return the RandomState singleton used by np.random.
|
||||
If seed is an int, return a new RandomState instance seeded with seed.
|
||||
If seed is already a RandomState instance, return it.
|
||||
Otherwise raise ValueError.
|
||||
"""
|
||||
if seed is None or seed is np.random:
|
||||
return np.random.mtrand._rand
|
||||
if isinstance(seed, (numbers.Integral, np.integer)):
|
||||
return np.random.RandomState(seed)
|
||||
if isinstance(seed, np.random.RandomState):
|
||||
return seed
|
||||
raise ValueError('%r cannot be used to seed a numpy.random.RandomState'
|
||||
' instance' % seed)
|
||||
|
||||
|
||||
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):
|
||||
stop_probability=1, random_state=None):
|
||||
"""Fit a model to data with the RANSAC (random sample consensus) algorithm.
|
||||
|
||||
RANSAC is an iterative algorithm for the robust estimation of parameters
|
||||
@@ -765,6 +783,12 @@ 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.
|
||||
random_state : int, RandomState instance or None, optional (default=None)
|
||||
If int, random_state is the seed used by the random number generator;
|
||||
If RandomState instance, random_state is the random number generator;
|
||||
If None, the random number generator is the RandomState instance used
|
||||
by `np.random`.
|
||||
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -849,6 +873,8 @@ def ransac(data, model_class, min_samples, residual_threshold,
|
||||
best_inlier_num = 0
|
||||
best_inlier_residuals_sum = np.inf
|
||||
best_inliers = None
|
||||
|
||||
random_state = check_random_state(random_state)
|
||||
|
||||
if min_samples < 0:
|
||||
raise ValueError("`min_samples` must be greater than zero")
|
||||
@@ -871,7 +897,7 @@ def ransac(data, model_class, min_samples, residual_threshold,
|
||||
|
||||
# choose random sample set
|
||||
samples = []
|
||||
random_idxs = np.random.randint(0, num_samples, min_samples)
|
||||
random_idxs = random_state.randint(0, num_samples, min_samples)
|
||||
for d in data:
|
||||
samples.append(d[random_idxs])
|
||||
|
||||
|
||||
@@ -193,8 +193,6 @@ def test_ellipse_model_residuals():
|
||||
|
||||
|
||||
def test_ransac_shape():
|
||||
np.random.seed(1)
|
||||
|
||||
# generate original data without noise
|
||||
model0 = CircleModel()
|
||||
model0.params = (10, 12, 3)
|
||||
@@ -208,7 +206,7 @@ def test_ransac_shape():
|
||||
data0[outliers[2], :] = (-100, -10)
|
||||
|
||||
# estimate parameters of corrupted data
|
||||
model_est, inliers = ransac(data0, CircleModel, 3, 5)
|
||||
model_est, inliers = ransac(data0, CircleModel, 3, 5, random_state=np.random.RandomState(1))
|
||||
|
||||
# test whether estimated parameters equal original parameters
|
||||
assert_equal(model0.params, model_est.params)
|
||||
@@ -217,10 +215,10 @@ def test_ransac_shape():
|
||||
|
||||
|
||||
def test_ransac_geometric():
|
||||
np.random.seed(1)
|
||||
random_state = np.random.RandomState(1)
|
||||
|
||||
# generate original data without noise
|
||||
src = 100 * np.random.random((50, 2))
|
||||
src = 100 * random_state.random_sample((50, 2))
|
||||
model0 = AffineTransform(scale=(0.5, 0.3), rotation=1,
|
||||
translation=(10, 20))
|
||||
dst = model0(src)
|
||||
@@ -232,7 +230,7 @@ def test_ransac_geometric():
|
||||
dst[outliers[2]] = (50, 50)
|
||||
|
||||
# estimate parameters of corrupted data
|
||||
model_est, inliers = ransac((src, dst), AffineTransform, 2, 20)
|
||||
model_est, inliers = ransac((src, dst), AffineTransform, 2, 20, random_state=random_state)
|
||||
|
||||
# test whether estimated parameters equal original parameters
|
||||
assert_almost_equal(model0.params, model_est.params)
|
||||
|
||||
Reference in New Issue
Block a user