当前位置: 首页 > news >正文

pcl案例六 基于配准的无序抓取

流程步骤:

1,先在source上找到抓取点。

        ——这里以obb的上表面的中点为抓取点。抓取时z方向垂直与表面

2,计算法向量

3,采样关键点

——这里点云数量少,特征角点少,所以采用了 直接uinform的下采样

4,计算fpfh的描述子

5,sample_consensus_prerejective  基于采样一致性的配准方案配准

——详细看了一下参数设置,这个设置参数还是很有考究的。

6,用的笨办法,去掉匹配到的target关键点,和关键点描述子。将剩下的点再进行二次配准。

7,计算每次匹配后的抓取点

——三个抓取点

8,这里没有用icp进一步配准(懒)。

感觉:没有halcon里面的find_surface_shape_model好用,在halcon里可能十行代码就可以搞定。但pcl里面,需要几百行。匹配效果和操作难度都要高很多。

下面附上我的粗糙代码,有玩的好的朋友欢迎指点

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <thread>
#include <pcl/io/ply_io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include<pcl/common/common.h>
#include<pcl/filters/project_inliers.h>
#include<pcl/common/transforms.h>
#include<pcl/filters/passthrough.h>
#include<pcl/filters/crop_box.h>
#include<pcl/features/normal_3d.h>
#include<pcl/filters/uniform_sampling.h>
#include<pcl/features/fpfh.h>
#include<pcl/registration/correspondence_estimation.h>
#include<pcl/registration//sample_consensus_prerejective.h>
#include<pcl/correspondence.h>
#include<pcl/registration/transformation_estimation_svd.h>
#include<pcl/recognition/trimmed_icp.h>
#include <pcl/registration/icp.h>
#include<pcl/registration/sample_consensus_prerejective.h>
#include<pcl/keypoints/iss_3d.h>#include "tolls.h"using namespace std;template<class point7>
class pcl::PointCloud<point7>::Ptr uniform_sample_by_radius(class pcl::PointCloud<point7>::Ptr inputcloud, float radius = 0.1)
{pcl::UniformSampling <point7 > usample;class pcl::PointCloud<point7>::Ptr source_keyp(new pcl::PointCloud<point7>);usample.setRadiusSearch(radius);usample.setInputCloud(inputcloud);usample.filter(*source_keyp);return source_keyp;
};int main ()
{pcl::PointCloud<pcl::PointXYZ>::Ptr test(new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr source(new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr target(new pcl::PointCloud<pcl::PointXYZ>);pcl::io::loadPLYFile("D:\\Desktop\\pacl_learning\\pick_up\\source0.ply",*source);pcl::io::loadPLYFile("D:\\Desktop\\pacl_learning\\pick_up\\target2.ply", *target);vector<int> a;pcl::removeNaNFromPointCloud(*source, *source, a);pcl::removeNaNFromPointCloud(*target, *target, a);//这里假设以obb包围盒的上表面中心。顶点作为抓取点,抓取时z方向垂直于上表面。pcl::PointXYZ pb_min, pb_max,pb_center;Eigen::Affine3f trans_obb = get_trans_obb<pcl::PointXYZ>(source, pb_min, pb_max, pb_center);test->push_back(pb_min);test->push_back(pb_max);test->push_back(pb_center);pcl::PointXYZ pb_top,tempt1(0, 0, pb_min.z);pb_top=pcl::transformPoint<pcl::PointXYZ> (tempt1,  trans_obb.inverse());test->push_back(pb_top);Eigen::Affine3f pick_0 = trans_obb.inverse();//pick_0就是我的抓取点。定义在外包围盒的上表面中心。z轴方向垂直于上表面。pick_0.translate(Eigen::Vector3f(pb_top.x-pb_center.x, pb_top.y - pb_center.y, pb_top.z - pb_center.z ));//对source回转以后,可以看到。坐标系与source的显示关系//pcl::transformPointCloud(*source, *source, pick_0.inverse());   //用于显示查看抓取点的准确性。cout << "picl_0" << endl;cout << pick_0.matrix()<< endl;//计算法线pcl::PointCloud<pcl::PointNormal>::Ptr source_normal = estimate_normal<pcl::PointXYZ>(source, 10);pcl::PointCloud<pcl::PointNormal>::Ptr target_normal = estimate_normal<pcl::PointXYZ>(target, 10);//求解点云分辨率,float resolution = get_cloud_resolution<pcl::PointXYZ>(source, 100);cout << "resolution___" << resolution << endl;//检索target_keyp的法线pcl::PointCloud<pcl::PointNormal>::Ptr target_kpn=uniform_sample_by_radius<pcl::PointNormal>(target_normal,2*resolution);pcl::PointCloud<pcl::PointNormal>::Ptr source_kpn = uniform_sample_by_radius<pcl::PointNormal>(source_normal,2 * resolution);cout << source_kpn->points.size() << endl;cout << target_kpn->points.size() << endl;//计算fpfh的值pcl::FPFHEstimation<pcl::PointNormal, pcl::PointNormal, pcl::FPFHSignature33> fpfh_est;pcl::search::KdTree<pcl::PointNormal>::Ptr tree(new pcl::search::KdTree<pcl::PointNormal>);fpfh_est.setSearchMethod(tree);fpfh_est.setKSearch(30);//计算source特征pcl::PointCloud<pcl::FPFHSignature33>::Ptr source_fpfh(new pcl::PointCloud<pcl::FPFHSignature33>);fpfh_est.setInputCloud(source_kpn);fpfh_est.setInputNormals(source_kpn);fpfh_est.compute(*source_fpfh);//计算target特征,如果特征点事pointnormal格式的话,setinputcloud和setinputnormals是点云指针。pcl::PointCloud<pcl::FPFHSignature33>::Ptr target_fpfh(new pcl::PointCloud<pcl::FPFHSignature33>);fpfh_est.setInputCloud(target_kpn);fpfh_est.setInputNormals(target_kpn);fpfh_est.compute(*target_fpfh);cout << "fpfh值计算完成" << endl;vector<Eigen::Affine3f> picl_points;int tempt = 1;while (tempt>0){//开始进行sample_consensus_prerejective  基于采样一致性的配准方案pcl::PointCloud<pcl::PointNormal>::Ptr source_keyp_trans(new pcl::PointCloud<pcl::PointNormal>);Eigen::Matrix4f trans_pose = Eigen::Matrix4f::Identity();pcl::SampleConsensusPrerejective<pcl::PointNormal, pcl::PointNormal, pcl::FPFHSignature33> align;align.setInputSource(source_kpn);align.setSourceFeatures(source_fpfh);align.setInputTarget(target_kpn);align.setTargetFeatures(target_fpfh);align.setMaximumIterations(5000);      //最大迭代次数align.setNumberOfSamples(3);         //每次选几个点来进行配准 3-6最佳align.setCorrespondenceRandomness(10);   //配准时近邻的几个点作为备选项align.setSimilarityThreshold(0.7);   //相似性阈值,排除不相似的点align.setTransformationEpsilon(1e-6);  //两次迭代值小于值则认为收敛 e-3_e-8之间 //align.setEuclideanFitnessEpsilon(1e-4);  //匹配后的点云均方差小于值则提前收敛,这个值感觉不太好设置align.setMaxCorrespondenceDistance(3*resolution);  //对应点的最大距离阈值,超过此值则认为是外点  一般为2-3倍的特征点resolutionalign.setInlierFraction(0.6);    //内点占比大于此值时停止匹配,不可过高,不达标的的时候会匹配失败align.align(*source_keyp_trans);trans_pose = align.getFinalTransformation();cout << align.hasConverged() << endl;if (align.hasConverged()){pcl::PointCloud<pcl::PointXYZ>::Ptr source_find(new pcl::PointCloud<pcl::PointXYZ>);pcl::transformPointCloud(*source, *source_find, trans_pose);pcl::PointCloud<pcl::PointXYZ>::Ptr target_pick(new pcl::PointCloud<pcl::PointXYZ>);Eigen::Affine3f trans_pose_affine(trans_pose);Eigen::Affine3f pick_up = trans_pose_affine * pick_0;picl_points.push_back(pick_up);cout << "抓取点" << endl;cout << pick_up.matrix() << endl;pcl::transformPointCloud(*target, *target_pick, pick_up.inverse());show_pointcloud<pcl::PointXYZ>(target_pick, 2, 100);pcl::PointCloud<pcl::PointNormal>::Ptr target_k_tempt(new pcl::PointCloud<pcl::PointNormal>);pcl::PointCloud<pcl::FPFHSignature33>::Ptr target_f_tempt(new pcl::PointCloud<pcl::FPFHSignature33>);vector<float> distance;vector<int> index;set<int> in_lier;//剔除匹配用到的关键点和关键特征pcl::search::KdTree<pcl::PointNormal>::Ptr tree3(new pcl::search::KdTree<pcl::PointNormal>);tree3->setInputCloud(target_kpn);for (auto point :source_keyp_trans->points){tree3->nearestKSearch(point, 20, index, distance);for (int i:index){in_lier.insert(i);}}for (int i =0;i< target_kpn->points.size();i++){if (in_lier.find(i)==in_lier.end()){target_k_tempt->push_back(target_kpn->points[i]);target_f_tempt->push_back(target_fpfh->points[i]);}}target_kpn = target_k_tempt;target_fpfh = target_f_tempt;//show_pointcloud<pcl::PointNormal>(target_kpn);}else { tempt = 0; }}return 0;
}


文章转载自:

http://56ygkYjt.pyncx.cn
http://9H6sG6HL.pyncx.cn
http://PfiLULaS.pyncx.cn
http://arvx3aga.pyncx.cn
http://MRZ52QBn.pyncx.cn
http://x3JvyRek.pyncx.cn
http://umAEcPXw.pyncx.cn
http://kPuvblUV.pyncx.cn
http://tDWuYhzk.pyncx.cn
http://JyFaYj6D.pyncx.cn
http://2O58V0fI.pyncx.cn
http://yg3rRC7N.pyncx.cn
http://GHjfnA0v.pyncx.cn
http://u6o9AdB8.pyncx.cn
http://wmw1gLbX.pyncx.cn
http://xxEPpF5L.pyncx.cn
http://XtR3ngsm.pyncx.cn
http://qSQ8RbiD.pyncx.cn
http://sWA60ldk.pyncx.cn
http://FwR7aR3j.pyncx.cn
http://lioYQwza.pyncx.cn
http://0E4CprR6.pyncx.cn
http://BeVodiZg.pyncx.cn
http://8eaUXJYf.pyncx.cn
http://tKLP9jOR.pyncx.cn
http://j3vRXu12.pyncx.cn
http://KysMbbxZ.pyncx.cn
http://m6ef4Ee8.pyncx.cn
http://RZ8LHWnI.pyncx.cn
http://VpokzmjF.pyncx.cn
http://www.dtcms.com/a/388687.html

相关文章:

  • 动态库和静态库的链接加载
  • 离线安装docker镜像
  • MySql索引性能优化
  • 【实战指南】WAF日志分析系统的生产部署:性能调优与最佳实践
  • OKZOO联合非小号TKW3,海上ALPHA WEB3派对启航
  • Java工程代码架构度量:从DSM到构建工具的深度实践
  • 车联网网络安全
  • AI模型压缩-详解
  • 从入门到熟练掌握MySQL:聚焦增删改查操作
  • 小目标检测的尺寸极限
  • deepblog insCode 初体验[设计待更新]
  • MySQL--事务
  • PolarDB-for-PostgreSQL CDC 总结
  • web:ts的构造函数
  • 深入解析API测试:从工具使用到自动化实践
  • 某机场网络安全改造方案详细解析
  • 本地大模型编程实战(34)使用faiss实现语义检索
  • Linux:线程池
  • 告别依赖混乱:Spring IoC 容器与 DI 依赖注入入门精讲
  • Python爬虫实战——使用NetNut网页解锁器获取亚马逊电商数据的高级策略与实践
  • 黑马JavaWeb+AI笔记 Day11 Web后端实战(登录模块)
  • Nocobase如何优雅的设置动态的自定义存储路径
  • 线性回归与 Softmax 回归:深度学习基础模型及训练逻辑解析
  • 第四章:职业初印象:打造你的个人品牌(3)
  • 大模型学习:什么是FastText模型架构
  • 【人工智能通识专栏】第十八讲:作业辅导提升
  • Python Matplotlib 布局
  • PHP自动计算文件大小,如:KB、MB、TB等
  • K近邻:从理论到实践
  • 微服务高可用流程讲解