【Open3D】如何在CMake/C++中调用Open3D

这篇具有很好参考价值的文章主要介绍了【Open3D】如何在CMake/C++中调用Open3D。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0. 引言

\qquad Open3D是点云的开源处理库,支持Python或C++。其Python已有较全的教程,也可以直接使用pip install open3d直接进行安装,而若想在C++中调用Open3D则麻烦一些,需要满足以下条件:

  • Open3D git源代码(本教程针对0.16.1的版本)
  • CMake >= 3.20
  • clang >= 7

分为以下几步进行:

  • 下载Open3D源代码
  • 升级CMake和匹配clang(如果有必要)
  • build & install Open3D
  • 在工程中引用Open3D

我们会将步骤1和3放在一起讲,有需要的朋友可以再回到步骤2。

参考链接1:GitHub中的教程
参考链接2:官网教程

1. 下载和安装Open3D

1.1.步骤详解

git clone --recursive https://github.com/intel-isl/Open3D.git
cd Open3D
mkdir build
cd build
cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=${HOME}/open3d_install ..
make install -j 12
cd ../..

可能的错误有以下几种:

  • make install出现Perimission Denied错误
  • clang或CMake版本过低错误
  • 找不到libc++或libc++abi
  1. make install如果报错,则改为sudo make install,Open3D会被安装在~/open3d_install/目录下,同时make install指令将软链接链接到/usr/的各个目录下。

  2. 如果提示CMake版本过低(如下图)或Clang版本过低,请执行步骤2。

CMake Error at CMakeLists.txt:1 (cmake_minimum_required):
  CMake 3.20 or higher is required.  You are running version 3.16.3
  1. 如果提示找不到libc++或libc++abi(如下图)
CMake Error at 3rdparty/find_dependencies.cmake:1317 (message):
  Cannot find matching libc++ and libc++abi libraries with version >=7.
Call Stack (most recent call first):
  CMakeLists.txt:486 (include)

请按照如下指令安装:

sudo apt-get install libc++-13-dev libc++abi-13-dev

上面版本13也可以替换成更高的版本,通过apt-cache search libc++-查找最高支持版本即可。

1.2.下载中遇到问题

  • 如若git下载过慢,请使用我上传到CSDN的Open3D代码,资源是永久免费的。另外不加--recursive也是可以的,编译的时候会再自动下载。
  • 在make install阶段Open3D需要下载第三方库约500MB的资源,如若出现下载过慢或失败的情况,请使用我上传到CSDN的资源(永久免费),解压到与build文件夹同目录的位置即可在make阶段跳过下载步骤。

2. 升级CMake和clang

2.1.CMake

\qquad 新版的Open3D要求cmake >= 3.20.1,有很多原生Ubuntu的CMake都是3.16的,这里需要卸载CMake重装。提供一种比较简单的方法:

pip install -U cmake
cmake --version

\qquad 这样就会通过pip下载最新版的cmake了,如果需要特定的版本,也可以加cmake==x.x.x类似的限定。通常pip下载完会提示某某路径未加入bin目录,例如我的就是/home/xxx/.local/cmake 未加入二进制目录,此时运行cmake --version仍然是旧版本,这种情况需要手动删除旧版本。
*如果未提示bin目录,且运行cmake --version时出现:

CMake Error: Could not find CMAKE_ROOT !!!
CMake has most likely not been installed correctly.

*则需要手动搜索pip下载的cmake:which cmake,以此得到它的下载路径。
删除旧版本

sudo rm -rf /usr/bin/cmake

后面的/usr/bin/cmake可以通过whereis cmake命令查询(第一个目录一般就是)
链接新版本

sudo ln -s ${HOME}/.local/cmake /usr/bin/cmake

此时再运行cmake --version,应该显示pip下载的CMake最新版本。

2.2.clang

通过clang --version查询clang的版本,如若版本低于7,请参照该博客下载clang和设置默认版本,一般情况只需要sudo apt-get install clang-10一条命令即可解决问题。

3. 在新的工程中调用Open3D

新工程里面的CMakeLists.txt怎么写,看个例子就可以了,以和之前的安装路径匹配:

cmake_minimum_required(VERSION 3.20.1)
project(open3d_example)
set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_CXX_FLAGS "-std=c++17")

set(Open3D_DIR ${HOME}/open3d_install/lib/cmake/Open3D)  

list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

# Open3D
find_package(Open3D HINTS REQUIRED)
list(APPEND Open3D_LIBRARIES dl)
if (Open3D_FOUND)
    message(STATUS "Found Open3D ${Open3D_VERSION}")
    link_directories(${Open3D_LIBRARY_DIRS})
endif()
# Add cpp files
add_executable(open3d_test src/open3d_test.cpp)
target_link_libraries(open3d_test ${Open3D_LIBRARIES})

cpp示例文件

// ----------------------------------------------------------------------------
// -                        Open3D: www.open3d.org                            -
// ----------------------------------------------------------------------------
// The MIT License (MIT)
//
// Copyright (c) 2018-2021 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"

void PrintPointCloud(const open3d::geometry::PointCloud &pointcloud) {
    using namespace open3d;

    bool pointcloud_has_normal = pointcloud.HasNormals();
    utility::LogInfo("Pointcloud has %d points.",
                     (int)pointcloud.points_.size());

    Eigen::Vector3d min_bound = pointcloud.GetMinBound();
    Eigen::Vector3d max_bound = pointcloud.GetMaxBound();
    utility::LogInfo(
            "Bounding box is: ({:.4f}, {:.4f}, {:.4f}) - ({:.4f}, {:.4f}, "
            "{:.4f})",
            min_bound(0), min_bound(1), min_bound(2), max_bound(0),
            max_bound(1), max_bound(2));

    for (size_t i = 0; i < pointcloud.points_.size(); i++) {
        if (pointcloud_has_normal) {
            const Eigen::Vector3d &point = pointcloud.points_[i];
            const Eigen::Vector3d &normal = pointcloud.normals_[i];
            utility::LogInfo("{:.6f} {:.6f} {:.6f} {:.6f} {:.6f} {:.6f}",
                             point(0), point(1), point(2), normal(0), normal(1),
                             normal(2));
        } else {
            const Eigen::Vector3d &point = pointcloud.points_[i];
            utility::LogInfo("{:.6f} {:.6f} {:.6f}", point(0), point(1),
                             point(2));
        }
    }
    utility::LogInfo("End of the list.");
}

void PrintHelp() {
    using namespace open3d;

    PrintOpen3DVersion();
    // clang-format off
    utility::LogInfo("Usage:");
    utility::LogInfo("    > PointCloud [pointcloud_filename]");
    // clang-format on
    utility::LogInfo("");
}

int main(int argc, char *argv[]) {
    using namespace open3d;

    utility::SetVerbosityLevel(utility::VerbosityLevel::Debug);

    if (argc != 2 ||
        utility::ProgramOptionExistsAny(argc, argv, {"-h", "--help"})) {
        PrintHelp();
        return 1;
    }

    auto pcd = io::CreatePointCloudFromFile(argv[1]);
    

    {
        utility::ScopeTimer timer("Normal estimation with KNN20");
        for (int i = 0; i < 20; i++) {
            pcd->EstimateNormals(open3d::geometry::KDTreeSearchParamKNN(20));
        }
    }
    std::cout << pcd->normals_[0] << std::endl;
    std::cout << pcd->normals_[10] << std::endl;

    {
        utility::ScopeTimer timer("Normal estimation with Radius 0.01666");
        for (int i = 0; i < 20; i++) {
            pcd->EstimateNormals(
                    open3d::geometry::KDTreeSearchParamRadius(0.01666));
        }
    }
    std::cout << pcd->normals_[0] << std::endl;
    std::cout << pcd->normals_[10] << std::endl;

    {
        utility::ScopeTimer timer("Normal estimation with Hybrid 0.01666, 60");
        for (int i = 0; i < 20; i++) {
            pcd->EstimateNormals(
                    open3d::geometry::KDTreeSearchParamHybrid(0.01666, 60));
        }
    }
    {
        utility::ScopeTimer timer("FPFH estimation with Radius 0.25");
        // for (int i = 0; i < 20; i++) {
        pipelines::registration::ComputeFPFHFeature(
                *pcd, open3d::geometry::KDTreeSearchParamRadius(0.25));
        //}
    }
    std::cout << pcd->normals_[0] << std::endl;
    std::cout << pcd->normals_[10] << std::endl;

    auto downpcd = pcd->VoxelDownSample(0.05);

    // 1. test basic pointcloud functions.

    geometry::PointCloud pointcloud;
    PrintPointCloud(pointcloud);

    pointcloud.points_.push_back(Eigen::Vector3d(0.0, 0.0, 0.0));
    pointcloud.points_.push_back(Eigen::Vector3d(1.0, 0.0, 0.0));
    pointcloud.points_.push_back(Eigen::Vector3d(0.0, 1.0, 0.0));
    pointcloud.points_.push_back(Eigen::Vector3d(0.0, 0.0, 1.0));
    PrintPointCloud(pointcloud);

    // 2. test pointcloud IO.

    const std::string filename_xyz("test.xyz");
    const std::string filename_ply("test.ply");

    if (io::ReadPointCloud(argv[1], pointcloud)) {
        utility::LogInfo("Successfully read {}", argv[1]);

        /*
        geometry::PointCloud pointcloud_copy;
        pointcloud_copy.CloneFrom(pointcloud);

        if (io::WritePointCloud(filename_xyz, pointcloud)) {
            utility::LogInfo("Successfully wrote {}",
        filename_xyz.c_str()); } else { utility::LogError("Failed to write
        {}", filename_xyz);
        }

        if (io::WritePointCloud(filename_ply, pointcloud_copy)) {
            utility::LogInfo("Successfully wrote {}",
        filename_ply); } else { utility::LogError("Failed to write
        {}", filename_ply);
        }
         */
    } else {
        utility::LogWarning("Failed to read {}", argv[1]);
    }

    // 3. test pointcloud visualization

    visualization::Visualizer visualizer;
    std::shared_ptr<geometry::PointCloud> pointcloud_ptr(
            new geometry::PointCloud);
    *pointcloud_ptr = pointcloud;
    pointcloud_ptr->NormalizeNormals();
    auto bounding_box = pointcloud_ptr->GetAxisAlignedBoundingBox();

    std::shared_ptr<geometry::PointCloud> pointcloud_transformed_ptr(
            new geometry::PointCloud);
    *pointcloud_transformed_ptr = *pointcloud_ptr;
    Eigen::Matrix4d trans_to_origin = Eigen::Matrix4d::Identity();
    trans_to_origin.block<3, 1>(0, 3) = bounding_box.GetCenter() * -1.0;
    Eigen::Matrix4d transformation = Eigen::Matrix4d::Identity();
    transformation.block<3, 3>(0, 0) = static_cast<Eigen::Matrix3d>(
            Eigen::AngleAxisd(M_PI / 4.0, Eigen::Vector3d::UnitX()));
    pointcloud_transformed_ptr->Transform(trans_to_origin.inverse() *
                                          transformation * trans_to_origin);

    visualizer.CreateVisualizerWindow("Open3D", 1600, 900);
    visualizer.AddGeometry(pointcloud_ptr);
    visualizer.AddGeometry(pointcloud_transformed_ptr);
    visualizer.Run();
    visualizer.DestroyVisualizerWindow();

    // 4. test operations
    *pointcloud_transformed_ptr += *pointcloud_ptr;
    visualization::DrawGeometries({pointcloud_transformed_ptr},
                                  "Combined Pointcloud");

    // 5. test downsample
    auto downsampled = pointcloud_ptr->VoxelDownSample(0.05);
    visualization::DrawGeometries({downsampled}, "Down Sampled Pointcloud");

    // 6. test normal estimation
    visualization::DrawGeometriesWithKeyCallbacks(
            {pointcloud_ptr},
            {{GLFW_KEY_SPACE,
              [&](visualization::Visualizer *vis) {
                  // EstimateNormals(*pointcloud_ptr,
                  //        open3d::KDTreeSearchParamKNN(20));
                  pointcloud_ptr->EstimateNormals(
                          open3d::geometry::KDTreeSearchParamRadius(0.05));
                  utility::LogInfo("Done.");
                  return true;
              }}},
            "Press Space to Estimate Normal", 1600, 900);

    // n. test end

    utility::LogInfo("End of the test.");
    return 0;
}

Cmake编译通过之后,运行./open3d_test xxx.pcd(应该pcd或者ply文件)应该出现如下信息:

[Open3D DEBUG] Format auto File ../download/BunnyMesh/BunnyMesh.ply
[Open3D DEBUG] Read geometry::PointCloud: 35947 vertices.
[Open3D DEBUG] [RemoveNonFinitePoints] 0 nan points have been removed.
[Open3D INFO] Normal estimation with KNN20 took 326.03 ms.
-0.220564
-0.970041
  0.10184
-0.369056
 0.618998
 0.693282
[Open3D INFO] Normal estimation with Radius 0.01666 took 1744.88 ms.
-0.337697
-0.926129
 0.168065
-0.193585
 0.557339
 0.807402
[Open3D INFO] Normal estimation with Hybrid 0.01666, 60 took 312.49 ms.
[Open3D INFO] FPFH estimation with Radius 0.25 took 24324.31 ms.
-0.238001
-0.966113
0.0999029
-0.311548
 0.593865
 0.741796
[Open3D DEBUG] Pointcloud down sampled from 35947 points to 32 points.
[Open3D INFO] Pointcloud has %d points.
[Open3D INFO] Bounding box is: (0.0000, 0.0000, 0.0000) - (0.0000, 0.0000, 0.0000)
[Open3D INFO] End of the list.
[Open3D INFO] Pointcloud has %d points.
[Open3D INFO] Bounding box is: (0.0000, 0.0000, 0.0000) - (1.0000, 1.0000, 1.0000)
[Open3D INFO] 0.000000 0.000000 0.000000
[Open3D INFO] 1.000000 0.000000 0.000000
[Open3D INFO] 0.000000 1.000000 0.000000
[Open3D INFO] 0.000000 0.000000 1.000000
[Open3D INFO] End of the list.
[Open3D DEBUG] Format auto File ../download/BunnyMesh/BunnyMesh.ply
[Open3D DEBUG] Read geometry::PointCloud: 35947 vertices.
[Open3D INFO] Successfully read ../download/BunnyMesh/BunnyMesh.pl

到此为止就可以证明你的Open3D C++库安装成功且被成功调用了,需注意由于时间推移,本教程针对的版本是open3d 0.16.1,如有新问题或解决方案,欢迎读者在评论区补充。文章来源地址https://www.toymoban.com/news/detail-417120.html

到了这里,关于【Open3D】如何在CMake/C++中调用Open3D的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于Open3D的点云处理17-Open3d的C++版本

    http://www.open3d.org/docs/latest/cpp_api.html http://www.open3d.org/docs/latest/getting_started.html#c http://www.open3d.org/docs/release/cpp_project.html#cplusplus-example-project https://github.com/isl-org/open3d-cmake-find-package https://github.com/isl-org/open3d-cmake-external-project https://github.com/isl-org/Open3D/releases Note: -DBUILD_SHARED_LIBS

    2024年02月09日
    浏览(62)
  • open3d 0.17.0的open3d.visualization.ViewControl类有bug

    在使用过程中发现 open3d.visualization.ViewControl 的如下方法,在 open3d 0.17.0 环境下不起作用,点云的显示视场还是默认配置;而在 open3d 0.16.0 环境下却正常工作。 rotate set_front set_lookat set_up set_zoom 上述测试代码在如下虚拟环境中进行过测试,均失败。 在如下虚拟环境中正常工作

    2024年02月21日
    浏览(58)
  • Open3D点云数据处理(一):VSCode配置python,并安装open3d教程

    专栏地址:https://blog.csdn.net/weixin_46098577/category_11392993.html 在很久很久以前,我写过这么一篇博客,讲的是open3d点云处理的基本方法。👇 当时是 PyCharm + Anaconda + python3.8 + open3d 0.13 已经是2023年了,现在有了全新版本。目前python由当年的3.8更新到了3.11版本,open3d也从0.13来到了

    2024年02月07日
    浏览(65)
  • 什么是open3D?

    目录 一、说明 二、如何安装open3d?  三、显示点云数据 3.1 显示点云场景数据 3.2 体素下采样 3.3 顶点法线估计         对于点云 处理,这里介绍哦pen3d,该软件和opencv同样是interl公司的产品。         Open3D 是一个开源库,支持快速开发处理 3D 数据的软件。 Open3D 前

    2024年02月03日
    浏览(59)
  • Open3D读取文件

    Open3D可以读取点云文件,三角网格文件,也可以读取图片。具体方法如下: 一、点云文件操作         Open3D支持的文件格式有xyz,xyzn,xyzrgb,pts,ply,pcd等文件。读取的方式也非常简单。data = o3d.io.read_point_cloud(\\\"文件名“) 1、读写文件         函数原型如下:    

    2024年02月08日
    浏览(51)
  • Open3D学习笔记

    Open3D是一个开源库,它支持处理3D数据的软件的快速开发。Open3D前端在C++和Python中有一些公开的数据结构和算法。后端经过高度优化,并设置为并行化。 PCL也是3D点云数据处理的优秀开源库,在C++平台上表现较好,但是在Python上python-pcl长时间不更新,维护少,不太好用,不建

    2024年02月01日
    浏览(48)
  • open3d io操作

    目录 1. read_image, write_image 2. read_point_cloud, write_point_cloud 3. 深度相机IO操作 4. Mesh文件读取 读取jpg. png. bmp等文件 image_io.py 读写点云pcd, ply等文件 point_cloud_io.py 读取深度相机 realsense_io.py  读取mesh网格数据,ply等文件 triangle_mesh_io.py

    2024年02月03日
    浏览(53)
  • open3d点云平移

    功能简介 open3d中点云的平移函数为:pcd.translate((tx, ty, tz), relative=True)。当relative为True时,(tx, ty, tz)表示点云平移的相对尺度,也就是平移了多少距离。当relative为False时,(tx, ty, tz)表示点云中心(质心)平移到的指定位置。质心可以坐标可以通过pcd.get_center()得到。 代码

    2024年01月22日
    浏览(80)
  • Open3D点云处理

    Open3D is an open-source library that supports rapid development of software that deals with 3D data. The Open3D frontend exposes a set of carefully selected data structures and algorithms in both C++ and Python. The backend is highly optimized and is set up for parallelization. Open3D是一个支持3D数据处理软件快速开发的开源库,在前端提供

    2023年04月17日
    浏览(57)
  • Open3d入门教程

    【英文版】 Open3D Python包通过 PyPI 和 Conda发布。 支持的Python版本: 3.6 3.7 3.8 支持的操作系统: Ubuntu 18.04+ macOS 10.14+ Windows 10 (64-bit) 如果你有其他Python版本(比如 Python 2) 或操作系统,请参考 编译源码 并从源代码处编译Open3D。 Pip (PyPI) 注意: 一般来说,我们建议使用虚拟环境 来集

    2024年02月16日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包