open3d使用fpfh做点云配准

2024-02-12 00:10
文章标签 使用 配准 做点 fpfh open3d

本文主要是介绍open3d使用fpfh做点云配准,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 写在前面
  • 准备
    • 编译open3d
    • 配准example
  • 编译demo
  • 配准测试
  • 参考

写在前面

1、环境:win10,cmake3.22.0-rc1,环境:win10,cmake3.22.0-rc1,已编译好的open3d 0.13
2、源码使用的是官方example
https://github.com/isl-org/Open3D/blob/master/examples/cpp/RegistrationRANSAC.cpp
3、建议先看一下open3d的demo:
open3d 0.13的c++版本使用demo https://blog.csdn.net/qq_41102371/article/details/12106527
4、所有资源已给出链接

准备

编译open3d

windows10编译open3d 0.13 https://blog.csdn.net/qq_41102371/article/details/121014372

配准example

将官方demo的CMakeLists.txt与配准源码RegistrationRANSAC.cpp
下载下来,放在文件夹open3d_fpfh_registration下
https://github.com/isl-org/open3d-cmake-find-package/blob/master/CMakeLists.txt
https://github.com/isl-org/Open3D/blob/master/examples/cpp/RegistrationRANSAC.cpp
并将CMakeLists.txt里面的Draw全部换成RegistrationRANSAC
CMakeLists.txt

# On Ubuntu 18.04, get the latest CMake from https://apt.kitware.com/.
cmake_minimum_required(VERSION 3.18)project(Open3DCMakeFindPackage LANGUAGES C CXX)# The options need to be the same as Open3D's default
# If Open3D is configured and built with custom options, you'll also need to
# specify the same custom options.
option(STATIC_WINDOWS_RUNTIME "Use static (MT/MTd) Windows runtime" ON)
if(STATIC_WINDOWS_RUNTIME)set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
else()set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
endif()# Find installed Open3D, which exports Open3D::Open3D
find_package(Open3D REQUIRED)add_executable(RegistrationRANSAC)
target_sources(RegistrationRANSAC PRIVATE RegistrationRANSAC.cpp)
target_link_libraries(RegistrationRANSAC PRIVATE Open3D::Open3D)# On Windows if BUILD_SHARED_LIBS is enabled, copy .dll files to the executable directory
if(WIN32)get_target_property(open3d_type Open3D::Open3D TYPE)if(open3d_type STREQUAL "SHARED_LIBRARY")message(STATUS "Copying Open3D.dll to ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>")add_custom_command(TARGET RegistrationRANSAC POST_BUILDCOMMAND ${CMAKE_COMMAND} -E copy${CMAKE_INSTALL_PREFIX}/bin/Open3D.dll${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>)endif()
endif()

RegistrationRANSAC.cpp,我在官方代码上做了些修改

// ----------------------------------------------------------------------------
// -                        Open3D: www.open3d.org                            -
// ----------------------------------------------------------------------------
// The MIT License (MIT)
//
// Copyright (c) 2018 www.open3d.org
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
// ----------------------------------------------------------------------------#include <Eigen/Dense>
#include <iostream>
#include <memory>#include "open3d/Open3D.h"using namespace open3d;
using namespace std;
std::tuple<std::shared_ptr<geometry::PointCloud>,std::shared_ptr<pipelines::registration::Feature>>
PreprocessPointCloud(const char *file_name, float voxel_size = 2.0) {//从文件读取点云auto pcd = open3d::io::CreatePointCloudFromFile(file_name);//降采样auto pcd_down = pcd->VoxelDownSample(voxel_size);std::cout << "read " << pcd->points_.size() << " points from " << file_name<< std::endl;std::cout << "voxel_size=" << voxel_size << ", after downsample "<< pcd_down->points_.size() << "points left" << endl;//计算法向量pcd_down->EstimateNormals(open3d::geometry::KDTreeSearchParamHybrid(voxel_size * 2, 30));//计算fpfh特征auto pcd_fpfh = pipelines::registration::ComputeFPFHFeature(*pcd_down,open3d::geometry::KDTreeSearchParamHybrid(voxel_size * 5, 100));return std::make_tuple(pcd_down, pcd_fpfh);
}void PrintHelp() {using namespace open3d;PrintOpen3DVersion();// clang-format offutility::LogInfo("Usage:");utility::LogInfo("    > RegistrationRANSAC source_pcd target_pcd  voxel_size [--method=feature_matching] [--mutual_filter] [--visualize]");// clang-format onutility::LogInfo("");
}int main(int argc, char *argv[]) {using namespace open3d;utility::SetVerbosityLevel(utility::VerbosityLevel::Debug);if (argc < 4 ||utility::ProgramOptionExistsAny(argc, argv, {"-h", "--help"})) {PrintHelp();return 1;}bool visualize = false;if (utility::ProgramOptionExists(argc, argv, "--visualize")) {visualize = true;}//visualize = true;bool mutual_filter = false;//if (utility::ProgramOptionExists(argc, argv, "--mutual_filter")) {//    mutual_filter = true;//}mutual_filter = true;// Prepare inputstd::shared_ptr<geometry::PointCloud> source, target;std::shared_ptr<pipelines::registration::Feature> source_fpfh, target_fpfh;//set voxel_sizefloat voxel_size = std::atof(argv[3]);std::cout << voxel_size << std::endl;float distance_threshold = voxel_size * 1.5;std::tie(source, source_fpfh) = PreprocessPointCloud(argv[1], voxel_size);std::tie(target, target_fpfh) = PreprocessPointCloud(argv[2], voxel_size);pipelines::registration::RegistrationResult registration_result;// Prepare checkersstd::vector<std::reference_wrapper<const pipelines::registration::CorrespondenceChecker>>correspondence_checker;auto correspondence_checker_edge_length =pipelines::registration::CorrespondenceCheckerBasedOnEdgeLength(0.9);auto correspondence_checker_distance =pipelines::registration::CorrespondenceCheckerBasedOnDistance(distance_threshold);correspondence_checker.push_back(correspondence_checker_edge_length);correspondence_checker.push_back(correspondence_checker_distance);registration_result = pipelines::registration::RegistrationRANSACBasedOnFeatureMatching(*source, *target, *source_fpfh, *target_fpfh,mutual_filter, distance_threshold,pipelines::registration::TransformationEstimationPointToPoint(false),3, correspondence_checker,pipelines::registration::RANSACConvergenceCriteria(1000000, 0.999));cout << endl<< "fpfh matrix:" << endl<< registration_result.transformation_ << endl;cout << "inlier(correspondence_set size):"<< registration_result.correspondence_set_.size() << endl;std::vector<std::pair<int, int>> correspondences_ransac;for (int m = 0; m < registration_result.correspondence_set_.size();++m) {std::pair<int, int> pair_(0, 0);pair_.first = registration_result.correspondence_set_[m][0];pair_.second = registration_result.correspondence_set_[m][1];correspondences_ransac.push_back(pair_);}// std::shared_ptr<open3d::geometry::LineSet>auto ransac_lineset =geometry::LineSet::CreateFromPointCloudCorrespondences(*source, *target, correspondences_ransac);std::shared_ptr<geometry::PointCloud> source_transformed_ptr(new geometry::PointCloud);std::shared_ptr<geometry::PointCloud> source_ptr(new geometry::PointCloud);std::shared_ptr<geometry::PointCloud> target_ptr(new geometry::PointCloud);*source_transformed_ptr = *source;*target_ptr = *target;*source_ptr = *source;target->PaintUniformColor({1, 0, 0});                  //红source->PaintUniformColor({0, 1, 0});                  //绿source_transformed_ptr->PaintUniformColor({0, 0, 1});  //蓝source_transformed_ptr->Transform(registration_result.transformation_);if (visualize) {visualization::DrawGeometries({target, source, source_transformed_ptr, ransac_lineset},"Registration result", 960, 900, 960, 100);}return 0;
}

编译demo

cd open3d_fpfh_registration
mkdir build
cd build
cmake -DOpen3D_ROOT="D:/Program Files/open3d" ..
cmake --build . --config Debug

成功生成RegistrationRANSAC.exe
在这里插入图片描述

配准测试

数据就用斯坦福的兔兔,http://graphics.stanford.edu/pub/3Dscanrep/bunny.tar.gz
解压后把bun000.ply和bun045.ply放在open3d_fpfh_registration目录下
回到命令行窗口:

start ./Debug/RegistrationRANSAC.exe ../bun045.ply ../bun000.ply 0.005 --visualize

若是其他数据,改一下…/bun045.ply …/bun000.ply 0.005 --visualize这几个参数就好,分别是source点云路径,target点云路径,降采样网格大小(根据点云大小和数据量来自行调节),–visualize加可视化

配准结果,红色是bun000,绿色是bun045,蓝色是bun045配准至bun000的结果,连线是连接的匹配上的fpfh特征
在这里插入图片描述

参考

文中已列出

--------------------------------------------------------------------------------------------诺有缸的高飞鸟202110

这篇关于open3d使用fpfh做点云配准的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/qq_41102371/article/details/121066031
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/701183

相关文章

python之uv使用详解

《python之uv使用详解》文章介绍uv在Ubuntu上用于Python项目管理,涵盖安装、初始化、依赖管理、运行调试及Docker应用,强调CI中使用--locked确保依赖一致性... 目录安装与更新standalonepip 安装创建php以及初始化项目依赖管理uv run直接在命令行运行pytho

C#使用Spire.XLS快速生成多表格Excel文件

《C#使用Spire.XLS快速生成多表格Excel文件》在日常开发中,我们经常需要将业务数据导出为结构清晰的Excel文件,本文将手把手教你使用Spire.XLS这个强大的.NET组件,只需几行C#... 目录一、Spire.XLS核心优势清单1.1 性能碾压:从3秒到0.5秒的质变1.2 批量操作的优雅

Kotlin 枚举类使用举例

《Kotlin枚举类使用举例》枚举类(EnumClasses)是Kotlin中用于定义固定集合值的特殊类,它表示一组命名的常量,每个枚举常量都是该类的单例实例,接下来通过本文给大家介绍Kotl... 目录一、编程枚举类核心概念二、基础语法与特性1. 基本定义2. 带参数的枚举3. 实现接口4. 内置属性三、

Java List 使用举例(从入门到精通)

《JavaList使用举例(从入门到精通)》本文系统讲解JavaList,涵盖基础概念、核心特性、常用实现(如ArrayList、LinkedList)及性能对比,介绍创建、操作、遍历方法,结合实... 目录一、List 基础概念1.1 什么是 List?1.2 List 的核心特性1.3 List 家族成

Go语言使用Gin处理路由参数和查询参数

《Go语言使用Gin处理路由参数和查询参数》在WebAPI开发中,处理路由参数(PathParameter)和查询参数(QueryParameter)是非常常见的需求,下面我们就来看看Go语言... 目录一、路由参数 vs 查询参数二、Gin 获取路由参数和查询参数三、示例代码四、运行与测试1. 测试编程路

Python使用python-pptx自动化操作和生成PPT

《Python使用python-pptx自动化操作和生成PPT》这篇文章主要为大家详细介绍了如何使用python-pptx库实现PPT自动化,并提供实用的代码示例和应用场景,感兴趣的小伙伴可以跟随小编... 目录使用python-pptx操作PPT文档安装python-pptx基础概念创建新的PPT文档查看

C#和Unity中的中介者模式使用方式

《C#和Unity中的中介者模式使用方式》中介者模式通过中介者封装对象交互,降低耦合度,集中控制逻辑,适用于复杂系统组件交互场景,C#中可用事件、委托或MediatR实现,提升可维护性与灵活性... 目录C#中的中介者模式详解一、中介者模式的基本概念1. 定义2. 组成要素3. 模式结构二、中介者模式的特点

MySQL中优化CPU使用的详细指南

《MySQL中优化CPU使用的详细指南》优化MySQL的CPU使用可以显著提高数据库的性能和响应时间,本文为大家整理了一些优化CPU使用的方法,大家可以根据需要进行选择... 目录一、优化查询和索引1.1 优化查询语句1.2 创建和优化索引1.3 避免全表扫描二、调整mysql配置参数2.1 调整线程数2.

C#中SortedSet的具体使用

《C#中SortedSet的具体使用》SortedSet是.NETFramework4.0引入的一个泛型集合类,它实现了一个自动排序的集合,内部使用红黑树数据结构来维护元素的有序性,下面就来介绍一下如... 目录基础概念主要特性创建和初始化基本创建方式自定义比较器基本操作添加和删除元素查询操作范围查询集合运

C# Opacity 不透明度的具体使用

《C#Opacity不透明度的具体使用》本文主要介绍了C#Opacity不透明度的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录WinFormsOpacity以下是一些使用Opacity属性的示例:设置窗体的透明度:设置按钮的透