天天看點

MATLAB點雲處理(十八):直線拟合(最小二乘 | RANSAC)

文章目錄

    • 1 最小二乘直線拟合
    • 2 RANSAC直線拟合
      • 2.1 RANSAC直線拟合函數
      • 2.2 代碼實作

1 最小二乘直線拟合

在 MATLAB點雲處理(十七):最小二乘多項式曲線拟合 已經作出講解。

2 RANSAC直線拟合

在 MATLAB點雲處理(十六):多項式曲線拟合(RANSAC | MSAC) 一文中已經給出了一種RANSAC直線拟合的方法,接下來介紹第二種RANSAC直線拟合的方法。

2.1 RANSAC直線拟合函數

ransac

— 從含有噪聲的資料中拟合直線

文法:

使用改進的RANSAC算法 —— M估計樣本一緻性(M-estimator sample consensus,MSAC)算法進行直線拟合

其中,

data

: 二維平面資料點集合

fitFcn

: 用于拟合模型的函數

distFcn

: 用于計算模型到資料之間距離的函數

sampleSize

: 每次采樣的點數

maxDistance

: 内點到模型的最大距離

2.2 代碼實作

示例:最小二乘直線拟合與RANSAC直線拟合的對比

代碼:

clc;
clear;

% 加載點雲
ptCloud = pcread('test.pcd');

% 提取xoy平面坐标點
xyPoints = ptCloud.Location;
x = xyPoints(:,1);
y = xyPoints(:,2);

figure;
plot(x,y,'.');
title('xoy平面投影點雲');
xlabel('X(m)');
ylabel('Y(m)');
zlabel('Z(m)');

% 最小二乘直線拟合
modelLeastSquares = polyfit(x,y,1);
x1 = linspace(min(x),max(x));
y1 = polyval(modelLeastSquares,x1);

% RANSAC直線拟合
sampleSize = 2; % 每次采樣的點數,直線為2
maxDistance = 0.1; % 内點到模型的最大距離
fitLineFcn = @(xyPoints) polyfit(xyPoints(:,1),xyPoints(:,2),1); % 拟合方式采用 polyfit,這裡不可以用x,y替換xyPoints(:,1),xyPoints(:,2)
evalLineFcn =  @(model, xyPoints) sum((y - polyval(model, x)).^2,2);% 距離估算函數
[modelRANSAC, inlierIdx] = ransac(xyPoints,fitLineFcn,evalLineFcn,sampleSize,maxDistance);% 執行RANSAC直線拟合,提取内點索引
modelInliers = polyfit(xyPoints(inlierIdx,1),xyPoints(inlierIdx,2),1);% 對模型内點進行最小二乘直線拟合

% 展示最小二乘直線拟合 和 RANSAC直線拟合的結果
figure;
plot(xyPoints(inlierIdx,1),xyPoints(inlierIdx,2),'.');		% 内點
hold on;
plot(xyPoints(~inlierIdx,1),xyPoints(~inlierIdx,2),'ro');	% 外點
hold on;
plot(x1,y1,'r-');											% 最小二乘直線拟合結果
hold on;

inlierPts = xyPoints(inlierIdx,:);
x2 = linspace(min(inlierPts(:,1)),max(inlierPts(:,1)));
y2 = polyval(modelInliers,x2);
plot(x2, y2, 'g-');											% RANSAC直線拟合結果
hold off;

title('最小二乘直線拟合 與 RANSAC直線拟合 對比');
xlabel('X(m)');
ylabel('Y(m)');
zlabel('Z(m)');
legend('内點','噪聲點','最小二乘直線拟合','RANSAC直線拟合','Location','NorthWest');
           

結果展示:

MATLAB點雲處理(十八):直線拟合(最小二乘 | RANSAC)
MATLAB點雲處理(十八):直線拟合(最小二乘 | RANSAC)

由于噪聲的存在,最小二乘法得到的拟合結果與預期結果相差甚遠,而RANSAC方法得到的結果較好。

相關連結:

最小二乘曲線拟合的C++實作

https://ww2.mathworks.cn/help/vision/ref/ransac.html