ransac

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 8, 2025 License: MIT Imports: 10 Imported by: 0

README

RANSAC Go

Build Status go.dev reference Go Report Card

This is a golang implementation of RANSAC. At a minimum, you provide a model which implements the Model interface. See simple_linear_regression.go for an example implementation and simple_linear_regression_test.go for its usage

Usage

func ExampleLinearRegressionModel_ransac() {
	// Example data points
	points := [][]float64{
		{0, 1},
		{1, 2},
		{2, 3},
		{3, 4},
		{16, 0},
		{-37, 43},
	}

	// Create a new LinearRegressionModel, which is an implementation of ransac.Model,
	// with a threshold of 0.5
	// note you provide an implementation of Model -- NewLinearRegressionModel
	// is provided by this module for demonstration purposes
	model := NewLinearRegressionModel(0.5)

	// Fit the model to the data points
	ransac.ModelFit(points, model,
		// Optional: Customize the RANSAC algorithm parameters
		// ransac.WithMaxIterations(1000),
		// ransac.WithTimeout(5 * time.Second),
		// ransac.WithNumberOfWorkers(4),
		// ransac.WithConsensusSetFit(true),
		// ransac.WithRand(...),
		// ... see options.go for more options
		//
		// This chooser was chosen for deterministic behavior during testing
		ransac.WithChooser(internal.OrderedChooser(uint(len(points)), model.MinimalFitpoints())),
	)

	// At this point your model is fitted to the data points
	fmt.Println(model)

	// And may be used to classify points as inliers or outliers
	for _, point := range points {
		if model.IsInlier(point) {
			fmt.Printf("Point %v is an inlier\n", point)
			continue
		}
		fmt.Printf("Point %v is an outlier\n", point)
	}

	// Output:
	// y = 1.00x + 1.00
	// Point [0 1] is an inlier
	// Point [1 2] is an inlier
	// Point [2 3] is an inlier
	// Point [3 4] is an inlier
	// Point [16 0] is an outlier
	// Point [-37 43] is an outlier
}

A note on efficiency

RANSAC is highly parallelizable, but to make full use of it here your model needs to also implement the Copier interface. Again, see simple_linear_regression.go for an example

Documentation

Overview

Package ransac implements random sample consensus (RANSAC)

See https://en.wikipedia.org/wiki/Random_sample_consensus

Index

Constants

View Source
const (
	// Termination condition
	MaxIterations terminationCondition = 1 << iota // Maximum number of iterations
	TimeLimit
)

Variables

View Source
var (
	ErrNoModelCopier     = errors.New("Model does not implement ModelCopier, cannot use multiple workers")
	ErrMinInliersZero    = errors.New("minimum inliers cannot be zero")
	ErrMinInliers        = errors.New("minimum inliers cannot be greater than the number of data points")
	ErrNumWorkersZero    = errors.New("number of workers cannot be zero")
	ErrMaxIterationsZero = errors.New("max iterations cannot be zero")
)

Functions

func ModelFit

func ModelFit[R internal.Number, M Model[R]](data [][]R, model M, options ...any) error

ModelFit fits the model to the supplied data using RANSAC

func RandomGonumChooser

func RandomGonumChooser(N, K uint) iter.Seq[[]int]

RandomGonumChooser generates random combinations of N choose K using gonum's combin.IndexToCombination function with a random index Note that it may yield the same combination multiple times

func WithChooser

func WithChooser(chooser iter.Seq[[]int]) func(*pNonGenericFields)

WithChooser sets the chooser function to be used for selecting random subsets of points The chooser function should yield combinations of indices for the points by default this uses the randomGonumChooser function

func WithConsensusSetFit

func WithConsensusSetFit(doConsensusSetFit bool) func(*pNonGenericFields)

WithNoConsensusSetFit enable or disables the consensus set fit typically done after the best model is found. This is enabled by default

func WithMaxIterations

func WithMaxIterations(n uint) func(*pNonGenericFields)

WithMaxIterations limits RANSAC to run only up to n iterations

func WithNoMaxIterations

func WithNoMaxIterations() func(*pNonGenericFields)

WithNoMaxIterations places no iteration limit on RANSAC In practice this means you must specify another termination condition such as WithTimeout

func WithNumberOfWorkers

func WithNumberOfWorkers(n uint) func(*pNonGenericFields)

WithNumberOfWorkers sets the number of goroutines to be used as workers By default this is set to runtime.GOMAXPROCS(0) -- which should be your number of CPUs

func WithRand

func WithRand(r *rand.Rand) func(*pNonGenericFields)

WithRand sets the random number generator to be used for selecting random subsets of points This is useful for testing purposes

func WithTimeout

func WithTimeout(d time.Duration) func(*pNonGenericFields)

WithMaxIterations limits RANSAC to run only up to duration d

Types

type Copier

type Copier[T any] interface {
	Copy() T
}

See CopyableModel

type CopyableModel

type CopyableModel[R internal.Number, M Model[R]] interface {
	Model[R]
	Copier[M]
}

CopyableModel represents a Model with a Copy() method. Since this RASNAC implementation modifies the internal state of a Model when it is fitted, each goroutine requires its own distinct model copy

type Model

type Model[R internal.Number] interface {
	MinimalFitpoints() uint // Minimal number of points needed to fit the model (e.g. 2 for line)
	Fit([][]R)              // Modifies internal state of model
	IsInlier([]R) bool      // Returns true if the point is an inlier
}

Model is RANSAC's interface to your model implementation The type parameter R is your number type for your model (typically float64)

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL