国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

使用PCL庫中PPF+ICP進行點云目標識別

這篇具有很好參考價值的文章主要介紹了使用PCL庫中PPF+ICP進行點云目標識別。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

#include <pcl/features/normal_3d.h>
#include <pcl/features/ppf.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/io/pcd_io.h>
#include <pcl/registration/ppf_registration.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <thread>
#include <pcl/registration/icp.h>

using namespace pcl;
using namespace std::chrono_literals;

const Eigen::Vector4f subsampling_leaf_size(1.5f,1.5f, 1.5f, 0.0f);//下采樣立方體大小
constexpr float normal_estimation_search_radius = 5.0f;//法線計算搜索半徑


int
main(int argc, char** argv)
{
    /// 讀取點云文件
    PointCloud<PointXYZ>::Ptr cloud_scene(new PointCloud<PointXYZ>());
    if (pcl::io::loadPCDFile("screws_M8_40_ronghe.pcd", *cloud_scene) < 0)
    {
        std::cout << "Error loading scene cloud." << std::endl;
        return (-1);
    }
    else
    {
        cout << "cloud_scene 讀取成功" << endl;
    }
   
    PointCloud<PointXYZ>::Ptr cloud_model(new PointCloud<PointXYZ>());
    if (pcl::io::loadPCDFile("screws_M8_40.pcd", *cloud_model) < 0)
    {
        std::cout << "Error loading model cloud." << std::endl;
        return (-1);
    }
    else
    {
        cout << "cloud_model 讀取成功" << endl;
    }

    //背景部分處理
    PointCloud<PointNormal>::Ptr cloud_scene_input(new PointCloud<PointNormal>());
    PointCloud<PointXYZ>::Ptr cloud_scene_subsampled(new PointCloud<PointXYZ>());
    //下采樣濾波
    VoxelGrid<PointXYZ> subsampling_filter;
    subsampling_filter.setInputCloud(cloud_scene);
    subsampling_filter.setLeafSize(subsampling_leaf_size);
    subsampling_filter.filter(*cloud_scene_subsampled);
    //計算背景法線
    PointCloud<Normal>::Ptr cloud_scene_normals(new PointCloud<Normal>());
    NormalEstimation<PointXYZ, Normal> normal_estimation_filter;
    normal_estimation_filter.setInputCloud(cloud_scene_subsampled);
    search::KdTree<PointXYZ>::Ptr search_tree(new search::KdTree<PointXYZ>);
    normal_estimation_filter.setSearchMethod(search_tree);
    normal_estimation_filter.setRadiusSearch(normal_estimation_search_radius);
    normal_estimation_filter.compute(*cloud_scene_normals);
    pcl::concatenateFields(*cloud_scene_subsampled, *cloud_scene_normals, *cloud_scene_input);
    cout << cloud_scene->size() << " down to" << cloud_scene_subsampled->size() << endl;
    //模型部分處理
    PointCloud<PointNormal>::Ptr cloud_model_input(new PointCloud<PointNormal>());
    PointCloud<PointXYZ>::Ptr cloud_model_subsampled(new PointCloud<PointXYZ>());
    //下采樣濾波
    VoxelGrid<PointXYZ> subsampling_filter2;
    subsampling_filter2.setInputCloud(cloud_model);
    subsampling_filter2.setLeafSize(subsampling_leaf_size);
    subsampling_filter2.filter(*cloud_model_subsampled);
    //計算背景法線
    PointCloud<Normal>::Ptr cloud_model_normals(new PointCloud<Normal>());
    NormalEstimation<PointXYZ, Normal> normal_estimation_filter2;
    normal_estimation_filter2.setInputCloud(cloud_model_subsampled);
    search::KdTree<PointXYZ>::Ptr search_tree2(new search::KdTree<PointXYZ>);
    normal_estimation_filter2.setSearchMethod(search_tree2);
    normal_estimation_filter2.setRadiusSearch(normal_estimation_search_radius);
    normal_estimation_filter2.compute(*cloud_model_normals);
    pcl::concatenateFields(*cloud_model_subsampled, *cloud_model_normals, *cloud_model_input);

    cout << cloud_model->size() << " down to" << cloud_model_subsampled->size() << endl;

   // pcl::PointCloud<pcl::PPFSignature>::Ptr cloud_model_ppf = pcl::PointCloud<pcl::PPFSignature>::Ptr(new pcl::PointCloud<pcl::PPFSignature>());
    PointCloud<PPFSignature>::Ptr cloud_model_ppf(new PointCloud<PPFSignature>());
    PPFEstimation<PointNormal, PointNormal, PPFSignature> ppf_estimator;
    ppf_estimator.setInputCloud(cloud_model_input);
    ppf_estimator.setInputNormals(cloud_model_input);
    ppf_estimator.compute(*cloud_model_ppf);//之前一直出現(xiàn)指針報錯???,加多維向量AGX后解決
    PPFHashMapSearch::Ptr hashmap_search(new PPFHashMapSearch( 2 * float(M_PI)/20 ,0.1f));
    hashmap_search->setInputFeatureCloud(cloud_model_ppf);
    

    visualization::PCLVisualizer viewer("PPF Object Recognition - Results");
    viewer.setBackgroundColor(0, 0, 0);
    viewer.addPointCloud(cloud_scene);
    viewer.spinOnce(10);
    PCL_INFO("Registering models to scene ...\n");

    將源點云和目標點云都轉化為無序點云
    //cloud_model_input->height = 1;
    //cloud_model_input->is_dense = false;
    //cloud_scene_input->height = 1;
    //cloud_scene_input->is_dense = false;
    PPFRegistration<PointNormal, PointNormal> ppf_registration;
    // set parameters for the PPF registration procedure
    ppf_registration.setSceneReferencePointSamplingRate(10);
    ppf_registration.setPositionClusteringThreshold(2.0f);
    ppf_registration.setRotationClusteringThreshold(12.0f / 180.0f * float(M_PI));
    ppf_registration.setSearchMethod(hashmap_search);
    ppf_registration.setInputSource(cloud_model_input);
    ppf_registration.setInputTarget(cloud_scene_input);
    無序點云
    PointCloud<PointNormal>::Ptr cloud_output_subsampled(new PointCloud<PointNormal>());

    ppf_registration.align(*cloud_output_subsampled);
    //出現(xiàn)數(shù)組越界訪問,無序點云OR有序點云,  //有疑問的地方?????????????????????????????
    //修改ppf_registration.hpp中的const auto aux_size = static_cast<std::size_t>(
        //   std::floor(2 * M_PI / search_method_->getAngleDiscretizationStep() + 1));

    //轉換點云XYZ格式
    PointCloud<PointXYZ>::Ptr cloud_output_subsampled_xyz(new PointCloud<PointXYZ>());
    for (const auto& point : (* cloud_output_subsampled).points)
        cloud_output_subsampled_xyz->points.emplace_back(point.x, point.y, point.z);

    Eigen::Matrix4f mat = ppf_registration.getFinalTransformation();
    std::cout << "PPF 變換矩陣:" << endl<<mat << endl;
    std::cout << "PPF score:" << ppf_registration.getFitnessScore() << endl;
    Eigen::Affine3f final_transformation(mat);
    //進行精確配準,采用ICP算法
    PointCloud<PointXYZ>::Ptr icp_result(new PointCloud<PointXYZ>());
    pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
    //輸入待配準點云和目標點云
    icp.setInputSource(cloud_model_subsampled);
    icp.setInputTarget(cloud_output_subsampled_xyz);
    //Set the max correspondence distance to 4cm (e.g., correspondences with higher distances will be ignored)
    icp.setMaxCorrespondenceDistance(10);//默認單位是米?
    //最大迭代次數(shù)
    icp.setMaximumIterations(1000);
    //兩次變化矩陣之間的差值
    icp.setTransformationEpsilon(1e-10);
    // 均方誤差
    icp.setEuclideanFitnessEpsilon(0.002);
    icp.align(*icp_result, mat);
    Eigen::Matrix4f icp_trans;
    icp_trans = icp.getFinalTransformation();
    std::cout << "icp變換矩陣:" << endl<<icp_trans << endl;
    std::cout << "icp score:" << icp.getFitnessScore() << endl;
    PointCloud<PointXYZ>::Ptr cloud_output(new PointCloud<PointXYZ>());
    pcl::transformPointCloud(
        *cloud_model, *cloud_output, icp_trans);

    pcl::visualization::PointCloudColorHandlerCustom<PointXYZ> output(cloud_output_subsampled_xyz, 255, 0, 0);
    pcl::visualization::PointCloudColorHandlerRandom<PointXYZ> random_color(cloud_output->makeShared());
    viewer.addPointCloud(cloud_output, random_color, "mode_name");
    //viewer.addPointCloud(cloud_output_subsampled_xyz, output, "dsd");
    while (!viewer.wasStopped()) {
        viewer.spinOnce(100);
        std::this_thread::sleep_for(100ms);
    }
    return 0;
}

在使用過程中踩到的坑:? ?

(1):PointCloud<PPFSignature>::Ptr cloud_model_ppf(new PointCloud<PPFSignature>());
? ? PPFEstimation<PointNormal, PointNormal, PPFSignature> ppf_estimator;
? ? ppf_estimator.setInputCloud(cloud_model_input);
? ? ppf_estimator.setInputNormals(cloud_model_input);
? ? ppf_estimator.compute(*cloud_model_ppf);

運行到ppf_estimator.compute(*cloud_model_ppf);一直報錯,是指針問題,打開屬性面板,選擇高級矢量擴展即可

pcl點云識別,PCL點云識別,c++,算法,開發(fā)語言,3d

(2)ppf_registration.align(*cloud_output_subsampled);運行到這里時一致報錯,彈出警告是vector越界訪問。解決辦法:

pcl點云識別,PCL點云識別,c++,算法,開發(fā)語言,3d

?修改這個庫文件,在floor函數(shù)后加一即可解決,問題出在floor函數(shù)向下取整,aux_size應該等于20,floor括號中算出來的是19.999.。。。,向下取整就變成19了,所以會出現(xiàn)越界訪問!!

附上最后運行效果:

pcl點云識別,PCL點云識別,c++,算法,開發(fā)語言,3d

?

?pcl點云識別,PCL點云識別,c++,算法,開發(fā)語言,3d

?綠色點云是找到的目標,加ICP是為了使位姿更準確文章來源地址http://www.zghlxwxcb.cn/news/detail-557208.html

到了這里,關于使用PCL庫中PPF+ICP進行點云目標識別的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 學習PCL庫:PCL庫中surface模塊

    學習PCL庫:PCL庫中surface模塊

    公眾號致力于點云處理,SLAM,三維視覺,高精地圖等領域相關內(nèi)容的干貨分享,歡迎各位加入,有興趣的可聯(lián)系dianyunpcl@163.com。未經(jīng)作者允許請勿轉載,歡迎各位同學積極分享和交流。 surface模塊介紹 PCL庫中的surface模塊提供了各種表面重建和擬合算法,根據(jù)任務的不同包含

    2024年01月22日
    瀏覽(42)
  • (學習筆記)PCL點云庫的基本使用

    (學習筆記)PCL點云庫的基本使用

    目錄 前言 1、理解點云庫 1.1、不同的點云類型 1.2、PCL中的算法 1.3、ROS的PCL接口 2、創(chuàng)建第一個PCL程序 2.1、創(chuàng)建點云 2.2、加載點云文件 2.3、創(chuàng)建點云文件 2.4、點云可視化 2.5、點云濾波和下采樣 2.5.1、點云濾波 ?2.5.2、點云下采樣 2.6、點云配準與匹配 ????????點云是一種

    2023年04月08日
    瀏覽(22)
  • 使用PCL濾波器實現(xiàn)點云裁剪

    使用PCL濾波器實現(xiàn)點云裁剪

    點云裁剪是根據(jù)提取劃分或者說標注出來的點云區(qū)域(ROI區(qū)域),對點云進行區(qū)域分離(點云裁剪和點云分割還是有區(qū)別的,所以這里用分離而不是分割)。根據(jù)已知的ROI區(qū)域,對點云進行裁剪。要么留下點云ROI區(qū)域,要么去除。 ROI區(qū)域一般都是一個矩形,即(x,y,width,

    2024年02月15日
    瀏覽(18)
  • PCL 使用點云創(chuàng)建數(shù)字高程模型DEM

    ? ?數(shù)字高程模型(Digital Elevation Model),簡稱DEM,是通過有限的地形高程數(shù)據(jù)實現(xiàn)對地面地形的數(shù)字化模擬(即地形表面形態(tài)的數(shù)字化表達),它是用一組有序數(shù)值陣列形式表示地面高程的一種實體地面模型,是數(shù)字地形模型(Digital Terrain Model,簡稱DTM)的一個分支,其它各種

    2024年02月13日
    瀏覽(16)
  • 點云配準--gicp原理與其在pcl中的使用

    點云配準--gicp原理與其在pcl中的使用

    總結:gicp引入了概率信息(使用協(xié)方差陣),提出了icp的統(tǒng)一模型,既可以解釋點到點和點到面的icp,也在新模型理論的基礎上,提出了一種面到面的icp。 論文原文:《Generalized-ICP》 在概率模型中假設存在配準中兩個點集, A ^ = { a i ^ } hat{A}=left{hat{a_{i}}right} A ^ = { a i ?

    2024年01月19日
    瀏覽(22)
  • PCL 點云變換

    PCL 點云變換

    一、原理簡述 兩片點云的剛體變換包含旋轉和平移,變換矩陣的含義如下: 1、旋轉矩陣 繞 x x

    2023年04月25日
    瀏覽(20)
  • pcl+vtk(三)QT中使用QVTKOpenGLNativeWidget的簡單教程以及案例,利用PCLVisualizer顯示點云

    pcl+vtk(三)QT中使用QVTKOpenGLNativeWidget的簡單教程以及案例,利用PCLVisualizer顯示點云

    先添加一個帶有ui的QT應用程序。 先拖出來一個QOpenGLWidget控件 修改布局如下: 然后將QOpenGLWidget控件提升為QVTKOpenGLNativeWidget控件,步驟如下: 右擊QOpenGLWidget窗口,選擇【提示為...】 ?輸入提升的類名稱為QVTKOpenGLNativeWidget ?此時需要把自動生成的qvtkopenglnativewidget.h修改為QV

    2024年01月25日
    瀏覽(40)
  • PCL 點云組件聚類

    該算法與歐式聚類、DBSCAN聚類很是類似,聚類過程如下所述: 1. 首先,我們需要提供一個種子點集合,對種子點集合進行初始的聚類操作,聚類的評估器(即聚類條件),可以指定為法向評估,也可以是距離評估,以此我們就可以提取出點云中各個位置的組件部分。 2. 合并

    2024年02月10日
    瀏覽(19)
  • PCL點云庫(2) - IO模塊

    PCL點云庫(2) - IO模塊

    目錄 2.1 IO模塊接口 2.2?PCD數(shù)據(jù)讀寫 (1) PCD數(shù)據(jù)解析 (2)PCD文件讀寫示例 2.3?PLY數(shù)據(jù)讀寫 (1)PLY數(shù)據(jù)解析 (2)PLY文件讀寫示例 2.4 OBJ數(shù)據(jù)讀寫 (1)OBJ數(shù)據(jù)解析 (2)OBJ文件讀寫示例 2.5?VTK數(shù)據(jù)讀寫 (1)VTK數(shù)據(jù)解析 (2)VTK文件讀寫示例 2.6 保存為PNG 參考文章:PCL函數(shù)庫

    2023年04月22日
    瀏覽(23)
  • 點云分割-pcl區(qū)域生長算法

    點云分割-pcl區(qū)域生長算法

    1、本文內(nèi)容 pcl的區(qū)域生長算法的使用和原理 2、平臺/環(huán)境 cmake, pcl 3、轉載請注明出處: https://blog.csdn.net/qq_41102371/article/details/131927376 參考:https://pcl.readthedocs.io/projects/tutorials/en/master/region_growing_segmentation.html#region-growing-segmentation https://blog.csdn.net/taifyang/article/details/124097186

    2024年02月15日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包