一、halcon平滑
smooth_object_model_3d
smooth_object_model_3d( : : ObjectModel3D, Method, GenParamName, GenParamValue : SmoothObjectModel3D)
halcon 代码:
dev_update_off ()
dev_close_window ()
HeightWindow := 400
WidthWindow := 400
dev_open_window (0, 0, HeightWindow, WidthWindow, 'black', WindowHandle1)
set_display_font (WindowHandle1, 16, 'mono', 'true', 'false')
Instructions := 'Rotate: Left button'
Instructions[1] := 'Zoom: Shift + left button'
Instructions[2] := 'Move: Ctrl + left button'
VisPose:=[-114.848, 90.4942, -245.079, 293.321, 348.313, 20.4772, 0]
read_object_model_3d ('test.ply', 'm', [], [], ObjectModel3D1, Status)
smooth_object_model_3d (ObjectModel3D1, 'mls', 'mls_kNN',60, SmoothObjectModel3D)
Title := 'Original'
visualize_object_model_3d (WindowHandle1, [ObjectModel3D1,SmoothObjectModel3D], [], VisPose, ['color', 'point_size'], ['white', 2], Title, [], Instructions, VisPose)
*
smooth_object_model_3d (ObjectModel3D1, 'mls', 'mls_force_inwards','true', SmoothObjectModel3D2)
visualize_object_model_3d (WindowHandle1, [ObjectModel3D1,SmoothObjectModel3D2], [], VisPose, ['color', 'point_size','disp_normals'], ['white', 2, 'true' ], Title, [], Instructions, VisPose)
smooth_object_model_3d (ObjectModel3D1, 'mls', 'mls_force_inwards','false', SmoothObjectModel3D2_1)
visualize_object_model_3d (WindowHandle1, [ObjectModel3D1,SmoothObjectModel3D2_1], [], VisPose, ['color', 'point_size','disp_normals'], ['white', 2, 'false'], Title, [], Instructions, VisPose)
smooth_object_model_3d (ObjectModel3D1, 'mls', 'mls_abs_sigma',1.1, SmoothObjectModel3D3)
visualize_object_model_3d (WindowHandle1, [ObjectModel3D1,SmoothObjectModel3D3], [], VisPose, ['color', 'point_size'], ['white', 2], Title, [], Instructions, VisPose)
smooth_object_model_3d (ObjectModel3D1, 'mls', 'mls_abs_sigma',0.1, SmoothObjectModel3D4)
visualize_object_model_3d (WindowHandle1, [ObjectModel3D1,SmoothObjectModel3D4], [], VisPose, ['color', 'point_size'], ['white', 2], Title, [], Instructions, VisPose)
结论:
smooth_object_model_3d 中点不会少,但是会改变一些点的位置
二、MLS 移动最小二乘法 PCL
1、平滑
// mls 平滑
int MLSsmooth(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_in, int PolynomialOrder, float Radius,pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mls_cloud)
{
if (cloud_in->size()<1 || Radius<0)
{
return -1;
}
if (PolynomialOrder>3|| PolynomialOrder<1)
{
PolynomialOrder = 2;
}
pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZRGB>);
tree->setInputCloud(cloud_in);
pcl::MovingLeastSquares < pcl::PointXYZRGB, pcl::PointXYZRGBNormal > mls;
mls.setComputeNormals(true); // 是否计算法向量
mls.setInputCloud(cloud_in);
//_________________________________
//mls.setUpsamplingMethod(,); // 上采样的方法
//mls.setUpsamplingRadius(0.1); // 函数规定了点云增长的区域。可以这样理解:把整个点云按照此半径划分成若干个子点云,然后一一索引进行点云增长。
//mls.setUpsamplingStepSize()//对于每个子点云处理时迭代的步长
//_________________________________
mls.setPolynomialFit(false); // 是否使用多项式拟合
mls.setPolynomialOrder(PolynomialOrder);// 默认是2
mls.setSearchMethod(tree);
mls.setSearchRadius(Radius); // 搜到半径
mls.process(*mls_cloud);
return 0;
}
移动最小二乘法MLS(Moving Lest Squares)简要介绍_Figure 09的博客-CSDN博客
https://www.cnblogs.com/zzk0/p/10468502.html
2、上采样
// mls 上采样
int MLS_Upsampling(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_in, int PolynomialOrder,
float searchRadius, float upsamping_radius, float step_size,pcl::PointCloud<pcl::PointXYZRGB>::Ptr mls_cloud)
{
if (cloud_in->size()<1 )
{
return -1;
}
pcl::MovingLeastSquares<pcl::PointXYZRGB, pcl::PointXYZRGB> mls;
mls.setInputCloud(cloud_in);
// 搜索树
pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZRGB>);
tree->setInputCloud(cloud_in);
mls.setSearchMethod(tree);
mls.setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZRGB,pcl::PointXYZRGB>::SAMPLE_LOCAL_PLANE);
mls.setSearchRadius(searchRadius);
// 设置上采用的半径
mls.setUpsamplingRadius(upsamping_radius);
// 设置步长的大小
mls.setUpsamplingStepSize(step_size);
mls.process(*mls_cloud);
return 0;
}
上采用并计算法向量:
// mls 上采样并计算法向量
int MLS_UpsamplingWithNormal(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_in, int PolynomialOrder,int tPointDensity,
float searchRadius, float upsamping_radius, float step_size,pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mls_cloud)
{
if (cloud_in->size()<1)
{
return -1;
}
if (cloud_in->size()<1)
{
return -1;
}
pcl::MovingLeastSquares<pcl::PointXYZRGB, pcl::PointXYZRGBNormal> mls;
mls.setInputCloud(cloud_in);
// 搜索树
pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZRGB>);
tree->setInputCloud(cloud_in);
mls.setSearchMethod(tree);
mls.setComputeNormals(true); // 计算法向量
mls.setPolynomialFit(true); // 拟合
mls.setPolynomialOrder(PolynomialOrder); // 设置阶数
mls.setPointDensity(tPointDensity);
mls.setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZRGB, pcl::PointXYZRGBNormal>::SAMPLE_LOCAL_PLANE);
mls.setSearchRadius(searchRadius);
// 设置上采用的半径
mls.setUpsamplingRadius(upsamping_radius);
// 设置步长的大小
mls.setUpsamplingStepSize(step_size);
mls.process(*mls_cloud);
return 0;
}