网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
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,
![img](https://img-blog.csdnimg.cn/img_convert/caef29644bba57ba965e52cb07eaa267.png)
![img](https://img-blog.csdnimg.cn/img_convert/1d98d5339df16de51c134edc8d64c70c.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
CE,
[外链图片转存中...(img-xbeis6VI-1715822674982)]
[外链图片转存中...(img-yEyapmDM-1715822674983)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**