001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2023 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit https://imagingbook.com for additional details. 008 ******************************************************************************/ 009package imagingbook.common.ransac; 010 011import imagingbook.common.geometry.basic.Pnt2d; 012import imagingbook.common.geometry.circle.GeometricCircle; 013import imagingbook.common.geometry.fitting.circle.algebraic.CircleFit3Points; 014import imagingbook.common.geometry.fitting.circle.algebraic.CircleFitAlgebraic; 015import imagingbook.common.geometry.fitting.circle.algebraic.CircleFitHyperSimple; 016 017/** 018 * <p> 019 * RANSAC detector for circles. See Sec. 12.1.4 of [1] for additional details. 020 * </p> 021 * <p> 022 * [1] W. Burger, M.J. Burge, <em>Digital Image Processing – An Algorithmic Introduction</em>, 3rd ed, Springer 023 * (2022). 024 * </p> 025 * 026 * @author WB 027 * @version 2022/11/19 028 * @see GeometricCircle 029 * @see RansacDetector 030 */ 031public class RansacCircleDetector extends RansacDetector<GeometricCircle>{ 032 033 /** 034 * Nested class extending {@link RansacDetector.RansacParameters} 035 * to specify additional RANSAC parameters. 036 */ 037 public static class Parameters extends RansacDetector.RansacParameters { 038 /** 039 * Constructor used to define default parameter values. 040 */ 041 public Parameters() { 042 this.randomPointDraws = 1000; 043 this.maxInlierDistance = 2.0; 044 this.minInlierCount = 70; 045 } 046 } 047 048 // constructors ------------------------------------ 049 050 /** 051 * Constructor using specific parameters. 052 * @param params RANSAC parameters 053 */ 054 public RansacCircleDetector(Parameters params) { 055 super(3, params); 056 } 057 058 /** 059 * Constructor using default parameters. 060 */ 061 public RansacCircleDetector() { 062 this(new Parameters()); 063 } 064 065 // ---------------------------------------------------------------- 066 067 @Override 068 GeometricCircle fitInitial(Pnt2d[] points) { 069 CircleFitAlgebraic fit = new CircleFit3Points(points); 070 return fit.getGeometricCircle(); 071 } 072 073 @Override 074 GeometricCircle fitFinal(Pnt2d[] inliers) { 075// CircleFitAlgebraic fit2 = new CircleFitPratt(inliers); // TODO: fails, check why 076 CircleFitAlgebraic fit2 = new CircleFitHyperSimple(inliers); 077 if (fit2.getParameters() == null) 078 throw new RuntimeException("circle fitFinal() failed!"); 079 return fit2.getGeometricCircle(); 080 } 081}