skimage2.measure.ransac#
- skimage2.measure.ransac(data, model_class, min_samples, residual_threshold, is_data_valid=None, is_model_valid=None, max_trials=100, stop_sample_num=inf, stop_residuals_sum=0, stop_probability=1, rng=None, initial_inliers=None, model_kwargs=None)[source]#
Fit a model to data with the RANSAC (random sample consensus) algorithm.
RANSAC is an iterative algorithm for the robust estimation of parameters from a subset of inliers from the complete data set. Each iteration performs the following tasks:
Select
min_samplesrandom samples from the original data and check whether the set of data is valid (seeis_data_valid).Estimate a model to the random subset (
model_cls.from_estimate(*data[random_subset]) and check whether the estimated model is valid (seeis_model_valid).Classify all data as inliers or outliers by calculating the residuals to the estimated model (
model_cls.residuals(*data)) - all data samples with residuals smaller than theresidual_thresholdare considered as inliers.Save estimated model as best model if number of inlier samples is maximal. In case the current estimated model has the same number of inliers, it is only considered as the best model if it has less sum of residuals.
These steps are performed either a maximum number of times or until one of the special stop criteria are met. The final model is estimated using all inlier samples of the previously determined best model.
- Parameters:
- datalist or tuple or array of shape (N,)
Data set to which the model is fitted, where N is the number of data points and the remaining dimension are depending on model requirements. If the model class requires multiple input data arrays (e.g. source and destination coordinates of
skimage.transform.AffineTransform), they can be optionally passed as tuple or list. Note, that in this case the functionsestimate(*data),residuals(*data),is_model_valid(model, *random_data)andis_data_valid(*random_data)must all take each data array as separate arguments.- model_classtype
Class with the following methods:
Either:
from_estimateclass method returning transform instance, as intform = model_class.from_estimate(*data, **kwargs); the resultingtformshould be truthy (bool(tform) == True) where estimation succeeded, or falsey (bool(tform) == False) where it failed; OR(deprecated)
estimateinstance method, returning flag to indicate successful estimation, as intform = model_class(); success = tform.estimate(*data).success == Truewhen estimation succeeded,success == Falsewhen it failed.
residuals(*data)
Your model should conform to the
RansacModelProtocolâ meaning implement all of the methods / attributes specified by the :class:RansacModelProctocol. An easy check to see whether that is the case is to useisinstance(MyModel, RansacModelProtocol). See https://docs.python.org/3/library/typing.html#typing.Protocol for more details.- min_samplesint, in range (0, N)
The minimum number of data points to fit a model to.
- residual_thresholdfloat, >0
Maximum distance for a data point to be classified as an inlier.
- is_data_validCallable, optional
This function is called with the randomly selected data before the model is fitted to it:
is_data_valid(*random_data).- is_model_validCallable, optional
This function is called with the estimated model and the randomly selected data:
is_model_valid(model, *random_data), .- max_trialsint, optional
Maximum number of iterations for random sample selection.
- stop_sample_numint, optional
Stop iteration if at least this number of inliers are found.
- stop_residuals_sumfloat, optional
Stop iteration if sum of residuals is less than or equal to this threshold.
- stop_probabilityfloat, optional, in range [0, 1]
RANSAC iteration stops if at least one outlier-free set of the training data is sampled with
probability >= stop_probability, depending on the current best modelâs inlier ratio and the number of trials. This requires to generate at least N samples (trials):N >= log(1 - probability) / log(1 - e**m)
where the probability (confidence) is typically set to a high value such as 0.99, e is the current fraction of inliers w.r.t. the total number of samples, and m is the min_samples value.
- rng{
numpy.random.Generator, int}, optional Pseudo-random number generator. By default, a PCG64 generator is used (see
numpy.random.default_rng()). Ifrngis an int, it is used to seed the generator.- initial_inliersarray-like of bool, shape (N,), optional
Initial samples selection for model estimation
- model_kwargsdict of {str: Any}, optional
The dict of keyword arguments passed to
from_estimateofmodel_class.
- Returns:
- modelobject
Best model with largest consensus set.
- inliersndarray of shape (N,)
Boolean mask of inliers classified as
True.
References
[1]âRANSACâ, Wikipedia, https://en.wikipedia.org/wiki/RANSAC
Examples
Generate ellipse data without tilt and add noise:
>>> from _skimage2.measure import EllipseModel >>> t = np.linspace(0, 2 * np.pi, 50) >>> xc, yc = 20, 30 >>> a, b = 5, 10 >>> x = xc + a * np.cos(t) >>> y = yc + b * np.sin(t) >>> data = np.column_stack([x, y]) >>> rng = np.random.default_rng(203560) # do not copy this value >>> data += rng.normal(size=data.shape)
Add some faulty data:
>>> data[0] = (100, 100) >>> data[1] = (110, 120) >>> data[2] = (120, 130) >>> data[3] = (140, 130)
Estimate ellipse model using all available data:
>>> model = EllipseModel.from_estimate(data) >>> np.round(model.center) array([71., 75.]) >>> np.round(model.axis_lengths) array([77., 13.]) >>> np.round(model.theta) 1.0
Next we estimate an ellipse model using RANSAC.
Note that the results are not deterministic, because the RANSAC algorithm uses some randomness. If you need the results to be deterministic, pass a seeded number generator with the
rngargument toransac.>>> ransac_model, inliers = ransac(data, EllipseModel, 20, 3, max_trials=50) >>> np.abs(np.round(ransac_model.center)) array([20., 30.]) >>> np.abs(np.round(ransac_model.axis_lengths)) array([10., 6.]) >>> np.abs(np.round(ransac_model.theta)) 2.0 >>> inliers array([False, False, False, False, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True], dtype=bool) >>> sum(inliers) > 40 True
RANSAC can be used to robustly estimate a geometric transformation. In this section, we also show how to use a proportion of the total samples, rather than an absolute number.
>>> from _skimage2.transform import SimilarityTransform >>> rng = np.random.default_rng() >>> src = 100 * rng.random((50, 2)) >>> model0 = SimilarityTransform(scale=0.5, rotation=1, ... translation=(10, 20)) >>> dst = model0(src) >>> dst[0] = (10000, 10000) >>> dst[1] = (-100, 100) >>> dst[2] = (50, 50) >>> ratio = 0.5 # use half of the samples >>> min_samples = int(ratio * len(src)) >>> model, inliers = ransac( ... (src, dst), ... SimilarityTransform, ... min_samples, ... 10, ... initial_inliers=np.ones(len(src), dtype=bool), ... ) >>> inliers array([False, False, False, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True])