第三届‘悉灵杯’-基于MV-EB435i-A相机的室内3D语义感知课题研究进展(二)
本篇文章为MV-EB435i-A相机采集数据处理部分研究进展介绍。

研究背景以及基本的环境部分请见第三届‘悉灵杯’-基于MV-EB435i-A相机的室内3D语义感知课题研究进展(一)

数据处理

color_bgr = image.reshape(-1, 3).astype(np.float32) color_rgb = color_bgr[:, [2, 1, 0]] point = np.hstack([point, color_rgb]) mask = np.any(point[:, :3] != 0, axis=1) filtered_point = point[mask] scaled_point = apply_uniform_sampling(filtered_point, 20000) scaled_point = normalize_point_cloud(scaled_point) np.save(os.path.join(save_dir, 'point', f"{stData.nFrameNum}.npy"), scaled_point)

异源数据融合获取有色点云的过程可以概述如下:首先,将图像数据从 BGR 格式转换为 RGB 格式,并将其展平为二维数组的形式。然后,将转换后的颜色信息与点云坐标合并,形成带有颜色属性的点云数据。通过创建掩码过滤掉无效的零坐标点,仅保留有效点云。接着,应用均匀采样方法对点云进行降采样,减少点数以便处理,并对点云数据进行归一化处理,以适应模型输入。最后,将处理后的有色点云数据保存为 .npy 文件,便于后续的使用和分析。这个过程结合了图像和点云数据的优势,使得每一个点不仅有空间坐标,还包含颜色信息,从而提升了点云的表达能力和可视化效果。

def normalize_point_cloud(point_cloud, range_min=-1, range_max=1): xyz = point_cloud[:, :3] min_vals_xyz = np.min(xyz, axis=0) max_vals_xyz = np.max(xyz, axis=0) max_range = np.max(max_vals_xyz - min_vals_xyz) centers_xyz = (min_vals_xyz + max_vals_xyz) / 2.0 normalized_xyz = (xyz - centers_xyz) / max_range normalized_xyz = normalized_xyz * (range_max - range_min) / 2.0 + (range_max + range_min) / 2.0 rgb = point_cloud[:, 3:] normalized_point_cloud = np.hstack([normalized_xyz, rgb]) return normalized_point_cloud def apply_uniform_sampling(pcd, number_of_points): if number_of_points >= pcd.shape[0]: print("返回原点云") return pcd step = pcd.shape[0] // number_of_points indices = np.arange(0, pcd.shape[0], step) if len(indices) > number_of_points: indices = indices[:number_of_points] sampled_pcd = pcd[indices] return sampled_pcd

首先,提取点云的XYZ坐标,并计算每个坐标轴上的最小值和最大值。然后,计算坐标轴上的最大范围,并确定点云的中心位置。接下来,将点云的每个坐标减去中心位置后,按最大范围进行缩放,使其在目标范围(默认是-1到1)内以适配模型计算。最后,将处理后的坐标与原始的颜色信息(RGB)合并,返回归一化的点云数据。下采样部分则是使用简单的均匀采样,根据模型输入选取,也不会丢失太多信息。

内参矫正:

def adjust_intrinsic(intrinsics, original_dim, new_dim): scale_x = new_dim[0] / original_dim[0] scale_y = new_dim[1] / original_dim[1] adjusted_intrinsics = intrinsics.copy() adjusted_intrinsics[0, 0] *= scale_x adjusted_intrinsics[1, 1] *= scale_y adjusted_intrinsics[0, 2] *= scale_x adjusted_intrinsics[1, 2] *= scale_y return adjusted_intrinsics

对于摄像头采集数据与模型输入数据不匹配问题,对数据进行缩放以适配本文使用的ESAM深度学习模型,对于参数也需要进行相应的调整。

ICP配准:

def register_point_clouds(source, target, voxel_size):
    """使用ICP算法配准点云"""
    source_down = source.voxel_down_sample(voxel_size)
    target_down = target.voxel_down_sample(voxel_size)
source_down.estimate_normals(o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))
target_down.estimate_normals(o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))
    
    threshold = voxel_size * 1.5
    result_icp = o3d.pipelines.registration.registration_icp(
        source_down, target_down, threshold, np.identity(4),
        o3d.pipelines.registration.TransformationEstimationPointToPoint())
    
    source.transform(result_icp.transformation)
    return source

对于多视角配准中的表面重建,使用ICP(迭代最近点)算法对源点云和目标点云进行配准。首先,分别对两个点云进行体素降采样以简化计算量,然后估计它们的法向量。接着,定义一个基于体素大小的阈值,并使用ICP算法计算源点云相对于目标点云的最佳变换矩阵。最后,将计算得到的变换应用于源点云,使其与目标点云对齐,从而实现多视角下的表面重建。

下面是具体数据格式处理的形式说明,便于理解:

imge:
shape: (640, 480, 3)
detype: uint8

depth:
shape: (640, 480, 1)
detype: ufloat16

pose:
shape: (4, 4)
detype: float32

point:
shape: (20000, 6) #(点云数,xyzrgb)
detype: float32

point_xyz:
min: -1
max: 1

point_rgb:
min: 0
max: 255

合成ply:
shape: (500000, 6) #(点云数,xyzrgb)
detype: float32
min: -1
max: 1
版权声明:本文为V社区用户原创内容,转载时必须标注文章的来源(V社区),文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:v-club@hikrobotics.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
上一篇

第三届‘悉灵杯’-基于MV-EB435i-A相机的室内3D语义感知课题研究进展(一)

下一篇

第三届‘悉灵杯’-基于MV-EB435i-A相机的室内3D语义感知课题研究最终提交

评论请先登录 登录
全部评论 0
Lv.0
0
关注
0
粉丝
0
创作
0
获赞
相关阅读
  • 现场运维异常处理手册
    2025-04-02 浏览 0
  • 海康移动机器人实施运维工程师认证资料目录
    2025-04-15 浏览 0
  • 【VM实现Halcon例程】光度立体法缺陷检测
    2025-04-17 浏览 0
  • 关节机器人防护分类分享
    2025-04-15 浏览 0

请升级浏览器版本

您正在使用的浏览器版本过低,请升级最新版本以获得更好的体验。

推荐使用以下浏览器