(11)点云数据处理学习——Colored point cloud registration(彩色点注册)

1、主要参考

(1)官网介绍

Colored point cloud registration — Open3D 0.16.0 documentation

2、原理和实现

 2.1原理

本教程演示了使用几何形状和颜色进行配准的ICP变体。实现了[Park2017]算法。颜色信息锁定沿切平面的对齐。因此,该算法比以往的点云配准算法精度更高,鲁棒性更强,运行速度与ICP配准算法相当。本教程使用来自ICP的符号。

2.2 辅助显示工具类

 为了演示彩色点云之间的对齐,draw_registration_result_original_color使用原始颜色呈现点云。

def draw_registration_result_original_color(source, target, transformation):
    source_temp = copy.deepcopy(source)
    source_temp.transform(transformation)
    o3d.visualization.draw_geometries([source_temp, target],
                                      zoom=0.5,
                                      front=[-0.2458, -0.8088, 0.5342],
                                      lookat=[1.7745, 2.2305, 0.9787],
                                      up=[0.3109, -0.5878, -0.7468])

 2.3待测试的点云数据

下面的代码从两个文件读取一个源点云和一个目标点云。使用单位矩阵作为注册的初始化。

注意:np.identity(4),相当于没有选择平移变换

(1)测试代码

import open3d as o3d
import numpy as np
from copy import deepcopy
# import time


def draw_registration_result_original_color(source, target, transformation):
    # source_temp = copy.deepcopy(source)
    source_temp = deepcopy(source)
    source_temp.transform(transformation)
    o3d.visualization.draw_geometries([source_temp, target],
                                      zoom=0.5,
                                      front=[-0.2458, -0.8088, 0.5342],
                                      lookat=[1.7745, 2.2305, 0.9787],
                                      up=[0.3109, -0.5878, -0.7468])


if __name__ == "__main__":
    print("1. Load two point clouds and show initial pose")
    demo_colored_icp_pcds = o3d.data.DemoColoredICPPointClouds()
    source = o3d.io.read_point_cloud(demo_colored_icp_pcds.paths[0])
    target = o3d.io.read_point_cloud(demo_colored_icp_pcds.paths[1])

    # draw initial alignment
    current_transformation = np.identity(4)
    draw_registration_result_original_color(source, target, current_transformation)

(2)下载的文件

 (3)显示的结果图

 2.4 点对面ICP对齐测试(Point-to-plane ICP)

我们首先使用点到平面ICP作为基线方法(baseline approach)。下面的可视化显示了未对齐的绿色三角形纹理。这是因为几何约束不能防止两个平面滑动

(1)测试代码

import open3d as o3d
import numpy as np
from copy import deepcopy
# import time


def draw_registration_result_original_color(source, target, transformation):
    # source_temp = copy.deepcopy(source)
    source_temp = deepcopy(source)
    source_temp.transform(transformation)
    o3d.visualization.draw_geometries([source_temp, target],
                                      zoom=0.5,
                                      front=[-0.2458, -0.8088, 0.5342],
                                      lookat=[1.7745, 2.2305, 0.9787],
                                      up=[0.3109, -0.5878, -0.7468])


if __name__ == "__main__":
    print("1. Load two point clouds and show initial pose")
    demo_colored_icp_pcds = o3d.data.DemoColoredICPPointClouds()
    source = o3d.io.read_point_cloud(demo_colored_icp_pcds.paths[0])
    target = o3d.io.read_point_cloud(demo_colored_icp_pcds.paths[1])

    # draw initial alignment
    current_transformation = np.identity(4)
    draw_registration_result_original_color(source, target, current_transformation)

    # point to plane ICP
    current_transformation = np.identity(4)
    print("2. Point-to-plane ICP registration is applied on original point")
    print("   clouds to refine the alignment. Distance threshold 0.02.")
    result_icp = o3d.pipelines.registration.registration_icp(
        source, target, 0.02, current_transformation,
        o3d.pipelines.registration.TransformationEstimationPointToPlane())
    print(result_icp)
    draw_registration_result_original_color(source, target,
                                            result_icp.transformation)

(2)测试结果

 测试的参数如下:

clouds to refine the alignment. Distance threshold 0.02.
RegistrationResult with fitness=9.745825e-01, inlier_rmse=4.220433e-03, and correspondence_set size of 62729
Access transformation to get result.

 3、彩色点云注册(Colored point cloud registration)

    彩色点云配准的核心函数是registration_colored_icp。在[Park2017]之后,它运行了一个联合优化目标的ICP迭代(详见点到点ICP)。

 其中T是要估计的变换矩阵。EC和EG分别是光度项和几何项。δ∈[0,1]是经经验确定的权重参数。几何术语EG与点对面ICP相同。

 其中K为当前迭代中的对应集。Np是点p的法线。颜色项EC测量点q(记为C(q))的颜色与其在p的切平面上的投影颜色之间的差值。

 其中Cp(⋅)是一个预先计算的函数,连续定义在p的切平面上。函数(⋅)将一个3D点投影到切平面上。详情请参考[Park2017]。为了进一步提高效率,[Park2017]提出了一个多尺度注册方案。这已在以下脚本中实现。

3.1 彩色对齐的代码测试

PS:注意,逐步收敛!注意,体素逐渐变小!!!

(1)代码

import open3d as o3d
import numpy as np
from copy import deepcopy
# import time


def draw_registration_result_original_color(source, target, transformation):
    # source_temp = copy.deepcopy(source)
    source_temp = deepcopy(source)
    source_temp.transform(transformation)
    o3d.visualization.draw_geometries([source_temp, target],
                                      zoom=0.5,
                                      front=[-0.2458, -0.8088, 0.5342],
                                      lookat=[1.7745, 2.2305, 0.9787],
                                      up=[0.3109, -0.5878, -0.7468])


if __name__ == "__main__":
    print("1. Load two point clouds and show initial pose")
    demo_colored_icp_pcds = o3d.data.DemoColoredICPPointClouds()
    source = o3d.io.read_point_cloud(demo_colored_icp_pcds.paths[0])
    target = o3d.io.read_point_cloud(demo_colored_icp_pcds.paths[1])

    # draw initial alignment
    current_transformation = np.identity(4)
    draw_registration_result_original_color(source, target, current_transformation)

    # point to plane ICP
    current_transformation = np.identity(4)
    print("2. Point-to-plane ICP registration is applied on original point")
    print("   clouds to refine the alignment. Distance threshold 0.02.")
    result_icp = o3d.pipelines.registration.registration_icp(
        source, target, 0.02, current_transformation,
        o3d.pipelines.registration.TransformationEstimationPointToPlane())
    print(result_icp)
    draw_registration_result_original_color(source, target,
                                            result_icp.transformation)


    # colored pointcloud registration
    # This is implementation of following paper
    # J. Park, Q.-Y. Zhou, V. Koltun,
    # Colored Point Cloud Registration Revisited, ICCV 2017
    voxel_radius = [0.04, 0.02, 0.01]
    max_iter = [50, 30, 14]
    current_transformation = np.identity(4)
    print("3. Colored point cloud registration")
    for scale in range(3):
        iter = max_iter[scale]
        radius = voxel_radius[scale]
        print([iter, radius, scale])

        print("3-1. Downsample with a voxel size %.2f" % radius)
        source_down = source.voxel_down_sample(radius)
        target_down = target.voxel_down_sample(radius)

        print("3-2. Estimate normal.")
        source_down.estimate_normals(
            o3d.geometry.KDTreeSearchParamHybrid(radius=radius * 2, max_nn=30))
        target_down.estimate_normals(
            o3d.geometry.KDTreeSearchParamHybrid(radius=radius * 2, max_nn=30))

        print("3-3. Applying colored point cloud registration")
        result_icp = o3d.pipelines.registration.registration_colored_icp(
            source_down, target_down, radius, current_transformation,
            o3d.pipelines.registration.TransformationEstimationForColoredICP(),
            o3d.pipelines.registration.ICPConvergenceCriteria(relative_fitness=1e-6,
                                                            relative_rmse=1e-6,
                                                            max_iteration=iter))
        current_transformation = result_icp.transformation
        print(result_icp)
    draw_registration_result_original_color(source, target,
                                            result_icp.transformation)

(2)显示的结果

(3)测试的参数

 (4)说明

总的来说,使用voxel_down_sample创建了3层多分辨率点云。法线是用顶点法线估计来计算的。从粗到细,每个层都调用核心配准函数registration_colored_icp。lambda_geometric是registration_colored_icp的一个可选参数,它决定了λ eg +(1−λ)EC在总能量中的λ∈[0,1]。

输出是两个点云的紧密对齐。注意墙上的绿色三角形。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要给点云数据添加仅包含RGB颜色信息的点云进行颜色可视化,可以使用 pcl::PointCloud<pcl::PointXYZRGB> 类型的点云数据结构。以下是一个简单的示例代码,以将一个白色的点云转换为红色的点云为例: ```cpp #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/visualization/cloud_viewer.h> int main (int argc, char** argv) { // 创建一个白色的点云 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); cloud->width = 100; cloud->height = 1; cloud->points.resize (cloud->width * cloud->height); for (size_t i = 0; i < cloud->points.size (); ++i) { cloud->points[i].x = 1024 * rand () / (RAND_MAX + 1.0f); cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f); cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f); } // 创建一个仅包含RGB颜色信息的点云 pcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_cloud (new pcl::PointCloud<pcl::PointXYZRGB>); colored_cloud->width = cloud->width; colored_cloud->height = cloud->height; colored_cloud->points.resize (colored_cloud->width * colored_cloud->height); for (size_t i = 0; i < colored_cloud->points.size (); ++i) { colored_cloud->points[i].x = cloud->points[i].x; colored_cloud->points[i].y = cloud->points[i].y; colored_cloud->points[i].z = cloud->points[i].z; colored_cloud->points[i].r = 255; colored_cloud->points[i].g = 0; colored_cloud->points[i].b = 0; } // 创建可视化窗口并显示点云 pcl::visualization::CloudViewer viewer ("Simple Cloud Viewer"); viewer.showCloud (colored_cloud); // 等待直到可视化窗口关闭 while (!viewer.wasStopped ()) { } return 0; } ``` 在上面的示例代码中,我们首先创建一个白色的点云(类型为 pcl::PointCloud<pcl::PointXYZ>),然后根据该点云的坐标信息创建另一个点云(类型为 pcl::PointCloud<pcl::PointXYZRGB>),并将其所有的颜色设置为红色。最后,我们使用 pcl::visualization::CloudViewer 类创建一个窗口并显示这个新的点云。注意,这里我们仅为点云中的每个设置了 RGB 颜色信息,而没有设置 Alpha 通道信息,因此点云中的每个都是不透明的。 当然,上面的代码只是一个简单的示例,你可以根据需要进行修改和扩展。例如,你可以从文件中读取点云数据,或者使用 pcl::PointCloud<pcl::PointXYZRGBA> 类型的点云数据结构,同时设置 Alpha 通道信息以实现半透明效果等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值