其他分享
首页 > 其他分享> > 散点拟合圆---RANSAC

散点拟合圆---RANSAC

作者:互联网

一、算法原理

随机样本一致性(Random Sample Consensus RANSAC) 是一种迭代方法,用于从包含异常值的观察数据中估计出数学模型参数,因此也可以理解为一种异常值检测方法。RANSAC的一个基本假设是,数据由内点("inliers")和外点("outliers")组成,其中内点是在一定误差范围内可以通过一些模型参数来解释的数据,外点是不符合模型的数据。RANSAC的另一个假设是,随机选取的样本数据都是内点,存在一个可以估计模型参数的过程,该模型可以最佳地解释或拟合该数据。

二、算法步骤

三、代码

3.1 伪代码




iterations = 0
bestFit = null
bestInliers = null
bestErr = 无穷大

while iterations < \(K\) do
MaybeInliers := 从数据集\(S\)中随机选择\(N\)个样本
maybeModel := 通过MaybeInliers中拟合的模型参数
alsoInliers := 空集
for 数据集中除MaybeInliers外的所有点pt do
  ifpt和现有模型的误差值小于 \(e\)
   将点pt添加至alsoInliers
  end if
end for
if 内点个数大小于\(T\) then
  // 内点已经足够多, 依据内点重新估计模型参数
  betterModel := 通过alsoInliersMaybeInliers估计模型参数
  thisErr := 模型估计后与数据集的误差
  if thisErr < bestErr then
   bestFit := betterModel
   bestErr := thisErr
    return bestFit
  end if
else
   if alsoInliers的内点数量 大于 bestInliers的内点数量 then
    bestInliers := alsoInliers + maybeInliers
   end if
end if
iterations增加1
end while

bestFit := 通过bestInliers估计模型参数

return bestFit


C++ 代码

    double Fitter::FitCircleByRANSAC(const std::vector<core::Point2>& pointArray, core::Point2& center, double& radius, const int iterNum, const double e, const float ratio)
	{
		const int N = pointArray.size();
		const int targetN = N * ratio;
		int iter = 0;
		std::vector<core::Point2> bestInliers;
		while (iter < iterNum) {
			std::set<int> seedIds;
			GetNRand(N, 3, seedIds);  // circle need 3 point
			if (seedIds.size() < 3) {
				break;
			}
			std::vector<core::Point2> seedPts;
			for (const int idx : seedIds) {
				seedPts.push_back(pointArray[idx]);
			}
			core::Point2 seedCenter;
			double seedR2 = 0.0;
			GetCircle(seedPts[0], seedPts[1], seedPts[2], seedCenter, seedR2);

			std::vector<core::Point2> maybeInliers;
			for (const core::Point2 pt : pointArray) {
				if (std::abs((pt.x - seedCenter.x) * (pt.x - seedCenter.x) + (pt.y - seedCenter.y) * (pt.y - seedCenter.y) - seedR2) < e) {
					maybeInliers.push_back(pt);
				}
			}

			if (maybeInliers.size() > targetN) {
				// it show the inliers is enough
				return FitCircleByLeastSquare(maybeInliers, center, radius);
			}
			else {
				if (maybeInliers.size() > bestInliers.size()) {
					bestInliers.swap(maybeInliers);
					for (const core::Point2 pt : seedPts) {
						bestInliers.push_back(pt);
					}
				}
			}

			++iter;
		}
		return FitCircleByLeastSquare(bestInliers, center, radius);
	}

参考链接

Random_sample_consensus

圆拟合算法

圆检测(续)- RANSAC

标签:RANSAC,const,pt,模型,---,散点,内点,bestInliers,参数
来源: https://www.cnblogs.com/xiaxuexiaoab/p/16335766.html