一、原理推導(dǎo)
最小二乘法 擬合平面是我們最常用的擬合平面的方法,但是有特殊的情況是用這種方法是不能擬合的,后續(xù)會加上這種擬合方法(RANSAC)。
matlab 最小二乘擬合平面(方法一) - 灰信網(wǎng)(軟件開發(fā)博客聚合)
平面方程:Ax+By+Cz+D=0;
?
二、Matlab 實現(xiàn)
1、隨機(jī)出來一些離散的點
>> clear
>> close all
>> % 隨機(jī)生成一組(x,y,z)這些點的坐標(biāo)離一個平面比較近
>> x0=1;L1=2;
>> y0=1;L2=2;
>> x=x0+rand(20,1)*L1;
>> y=y0+rand(20,1)*L2;
>> z=1+2*x+3*y;
>> scatter3(x,y,z,'filled')
??
2、將其寫成矩陣的形式:
x_a=sum(x)/length(data);% length(data)==20
y_a=sum(y)/length(data);
z_a=sum(z)/length(data);
% 平方的均值====================================================
xx_a=sum(x.*x)/length(data);
yy_a=sum(y.*y)/length(data);
zz_a=sum(z.*z)/length(data);
xy_a=sum(x.*y)/length(data);
xz_a=sum(x.*z)/length(data);
yz_a=sum(y.*z)/length(data);
?3、求出a0? a1 a2也就是 -A/C? ?-B/C? ?-D/C
b=[xz_a;yz_a;z_a];
XYZ=A^-1 *b; % 方程求系數(shù)
a0=XYZ(1); % -A/C
a1=XYZ(2); % -B/C
a2=XYZ(3); % -D/C
4、求平面法向量
V=[a0 a1 -1];% 平面法向量
nor=norm(V); % 向量的模
normalize_V=[a0/nor a2/nor -1/nor]; % 平面法向量歸一化
5、?開始繪制圖像
scatter3(x,y,z,'filled')
hold on;
xfit=min(x):0.1:max(x); % 坐標(biāo)系的坐標(biāo)
yfit=min(y):0.1:max(y);
[XF,YF]=meshgrid(xfit,yfit);% 生產(chǎn)XY點列
ZF=a0*XF+a1*YF+a2; %計算Z的值
% 顯示
mesh(XF,YF,ZF)
clear
close all
% 隨機(jī)生成一組(x,y,z)這些點的坐標(biāo)離一個平面比較近
x0=1;L1=2;
y0=1;L2=2;
x=x0+rand(20,1)*L1;
y=y0+rand(20,1)*L2;
z=1+2*x+3*y;
scatter3(x,y,z,'filled')
hold on;
data=[x,y,z];
x=data(:,1);
y=data(:,2);
z=data(:,3);
x_a=sum(x)/length(data);% length(data)==20
y_a=sum(y)/length(data);
z_a=sum(z)/length(data);
% 平方的均值====================================================
xx_a=sum(x.*x)/length(data);
yy_a=sum(y.*y)/length(data);
zz_a=sum(z.*z)/length(data);
xy_a=sum(x.*y)/length(data);
xz_a=sum(x.*z)/length(data);
yz_a=sum(y.*z)/length(data);
% 方程組的系數(shù)矩陣
A=[xx_a xy_a x_a;
xy_a yy_a y_a;
x_a y_a 1];
b=[xz_a;yz_a;z_a];
XYZ=A^-1 *b; % 方程求系數(shù)
a0=XYZ(1); % -A/C
a1=XYZ(2); % -B/C
a2=XYZ(3); % -D/C
V=[a0 a1 -1];% 平面法向量
nor=norm(V); % 向量的模
normalize_V=[a0/nor a2/nor -1/nor]; % 平面法向量歸一化
% 開始繪制圖像
scatter3(x,y,z,'filled')
hold on;
xfit=min(x):0.1:max(x); % 坐標(biāo)系的坐標(biāo)
yfit=min(y):0.1:max(y);
[XF,YF]=meshgrid(xfit,yfit);% 生產(chǎn)XY點列
ZF=a0*XF+a1*YF+a2; %計算Z的值
% 顯示
mesh(XF,YF,ZF)
三維點集擬合:平面擬合、RANSAC、ICP算法_wishchin的博客-CSDN博客_三維曲面擬合算法文章來源:http://www.zghlxwxcb.cn/news/detail-572050.html
?PCL 基于PCA的平面擬合
文章來源地址http://www.zghlxwxcb.cn/news/detail-572050.html
?PCL的setIndices?函數(shù)
template <typename PointT> void
pcl::PCLBase<PointT>::setIndices (size_t row_start, size_t col_start, size_t nb_rows, size_t nb_cols)
{
if ((nb_rows > input_->height) || (row_start > input_->height))
{
PCL_ERROR ("[PCLBase::setIndices] cloud is only %d height", input_->height);
return;
}
if ((nb_cols > input_->width) || (col_start > input_->width))
{
PCL_ERROR ("[PCLBase::setIndices] cloud is only %d width", input_->width);
return;
}
size_t row_end = row_start + nb_rows;
if (row_end > input_->height)
{
PCL_ERROR ("[PCLBase::setIndices] %d is out of rows range %d", row_end, input_->height);
return;
}
size_t col_end = col_start + nb_cols;
if (col_end > input_->width)
{
PCL_ERROR ("[PCLBase::setIndices] %d is out of columns range %d", col_end, input_->width);
return;
}
indices_.reset (new std::vector<int>);
indices_->reserve (nb_cols * nb_rows);
for(size_t i = row_start; i < row_end; i++)
for(size_t j = col_start; j < col_end; j++)
indices_->push_back (static_cast<int> ((i * input_->width) + j));
fake_indices_ = false;
use_indices_ = true;
}
#if 1 // PCA的平面擬合
int main()
{
// Findnowd();
string path = "C:\\Users\\Albert\\Desktop\\pcd\\plane.pcd";
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 創(chuàng)建點云(指針)
if (pcl::io::loadPCDFile<pcl::PointXYZ>(path, *cloud) == -1) //* 讀入PCD格式的文件,如果文件不存在,返回-1
{
PCL_ERROR("Couldn't read file test_pcd.pcd \n"); //文件不存在時,返回錯誤,終止程序。
return 0;
}
cout << " 點云的大小 : " << cloud->size() << endl;
pcl::PCA<pcl::PointXYZ> pca;
pca.setInputCloud(cloud);
Eigen::Matrix3f ve=pca.getEigenVectors();
cout << "矩陣:" << endl;
cout << ve << endl;
float A, B, C, D;
A = ve.col(2).row(0).value();
B = ve.col(2).row(1).value();
C = ve.col(2).row(2).value();
cout << "平面參數(shù): " << endl;
cout << " A:" << A << endl;
cout << " B:" << B << endl;
cout << " C:" << C << endl;
//計算點云的質(zhì)心
Eigen::Vector4d centroid;
pcl::compute3DCentroid(*cloud, centroid);
D = -(A * centroid[0] + B * centroid[1] + C * centroid[2]);
cout << " D:" << D << endl;
system("pause");
return (0);
}
#endif
到了這里,關(guān)于Matlab 最小二乘法 擬合平面 (PCL PCA擬合平面)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!