当前位置: 首页 > article >正文

《Keras 3 使用 PointNet 进行点云分段》:此文为AI自动翻译

使用 PointNet 进行点云分段

作者:Soumik Rakshit、Sayak Paul
创建日期:2020/10/23
最后修改日期:2020/10/24
描述:实现基于 PointNet 的模型,用于分割点云。

(i) 此示例使用 Keras 3

 在 Colab 中查看 

 GitHub 源


介绍

“点云”是用于存储几何形状数据的一种重要数据结构类型。 由于其格式不规则,它经常被转换为 常规 3D 体素网格或图像集合,然后再用于深度学习应用程序, 该步骤会使数据不必要地变大。 PointNet 系列模型通过直接使用点云来解决这个问题,遵循 点数据的 permutation-invariance 属性。PointNet 系列 模型提供简单、统一的架构 适用于从对象分类零件分割场景语义解析的各种应用。

在此示例中,我们演示了 PointNet 架构的实现 用于形状分割。

引用

  • PointNet:用于 3D 分类和分割的点集深度学习
  • 使用 PointNet 进行点云分类
  • 空间变换器网络

进口

import os
import json
import random
import numpy as np
import pandas as pd
from tqdm import tqdm
from glob import glob

import tensorflow as tf  # For tf.data
import keras
from keras import layers

import matplotlib.pyplot as plt

下载 Dataset

ShapeNet 数据集是一项持续的努力,旨在建立一个注释丰富的 3D 形状的大规模数据集。ShapeNetCore 是完整 ShapeNet 的子集 具有干净的单个 3D 模型和手动验证的类别和对齐方式的数据集 附注。它涵盖了 55 个常见对象类别,具有大约 51300 个独特的 3D 模型。

在这个例子中,我们使用 PASCAL 3D+ 的 12 个对象类别之一, 作为 ShapenetCore 数据集的一部分包含在内。

dataset_url = "https://git.io/JiY4i"

dataset_path = keras.utils.get_file(
    fname="shapenet.zip",
    origin=dataset_url,
    cache_subdir="datasets",
    hash_algorithm="auto",
    extract=True,
    archive_format="auto",
    cache_dir="datasets",
)

加载数据集

我们解析数据集元数据,以便轻松地将模型类别映射到其 将相应的目录和分段类设置为颜色,以便 可视化。

with open("/tmp/.keras/datasets/PartAnnotation/metadata.json") as json_file:
    metadata = json.load(json_file)

print(metadata)
{'Airplane': {'directory': '02691156', 'lables': ['wing', 'body', 'tail', 'engine'], 'colors': ['blue', 'green', 'red', 'pink']}, 'Bag': {'directory': '02773838', 'lables': ['handle', 'body'], 'colors': ['blue', 'green']}, 'Cap': {'directory': '02954340', 'lables': ['panels', 'peak'], 'colors': ['blue', 'green']}, 'Car': {'directory': '02958343', 'lables': ['wheel', 'hood', 'roof'], 'colors': ['blue', 'green', 'red']}, 'Chair': {'directory': '03001627', 'lables': ['leg', 'arm', 'back', 'seat'], 'colors': ['blue', 'green', 'red', 'pink']}, 'Earphone': {'directory': '03261776', 'lables': ['earphone', 'headband'], 'colors': ['blue', 'green']}, 'Guitar': {'directory': '03467517', 'lables': ['head', 'body', 'neck'], 'colors': ['blue', 'green', 'red']}, 'Knife': {'directory': '03624134', 'lables': ['handle', 'blade'], 'colors': ['blue', 'green']}, 'Lamp': {'directory': '03636649', 'lables': ['canopy', 'lampshade', 'base'], 'colors': ['blue', 'green', 'red']}, 'Laptop': {'directory': '03642806', 'lables': ['keyboard'], 'colors': ['blue']}, 'Motorbike': {'directory': '03790512', 'lables': ['wheel', 'handle', 'gas_tank', 'light', 'seat'], 'colors': ['blue', 'green', 'red', 'pink', 'yellow']}, 'Mug': {'directory': '03797390', 'lables': ['handle'], 'colors': ['blue']}, 'Pistol': {'directory': '03948459', 'lables': ['trigger_and_guard', 'handle', 'barrel'], 'colors': ['blue', 'green', 'red']}, 'Rocket': {'directory': '04099429', 'lables': ['nose', 'body', 'fin'], 'colors': ['blue', 'green', 'red']}, 'Skateboard': {'directory': '04225987', 'lables': ['wheel', 'deck'], 'colors': ['blue', 'green']}, 'Table': {'directory': '04379243', 'lables': ['leg', 'top'], 'colors': ['blue', 'green']}} 

在此示例中,我们训练 PointNet 对模型的各个部分进行分割。Airplane

points_dir = "/tmp/.keras/datasets/PartAnnotation/{}/points".format(
    metadata["Airplane"]["directory"]
)
labels_dir = "/tmp/.keras/datasets/PartAnnotation/{}/points_label".format(
    metadata["Airplane"]["directory"]
)
LABELS = metadata["Airplane"]["lables"]
COLORS = metadata["Airplane"]["colors"]

VAL_SPLIT = 0.2
NUM_SAMPLE_POINTS = 1024
BATCH_SIZE = 32
EPOCHS = 60
INITIAL_LR = 1e-3

构建数据集

我们从 Airplane 点云生成以下内存数据结构,并且 他们的标签:

  • point_clouds是表示 中的点云数据的对象列表 X、Y 和 Z 坐标的形式。轴 0 表示 点云,而轴 1 表示坐标。 是列表 将每个坐标的标签表示为字符串(主要需要 可视化目的)。np.arrayall_labels
  • test_point_clouds的格式与 相同,但没有 对应于点云的标签。point_clouds
  • all_labels是表示点云标签的对象列表 对于每个坐标,对应于列表。np.arraypoint_clouds
  • point_cloud_labels是表示点云的对象列表 每个坐标的标签,采用 one-hot 编码形式,对应于列表。np.arraypoint_clouds
point_clouds, test_point_clouds = [], []
point_cloud_labels, all_labels = [], []

points_files = glob(os.path.join(points_dir, "*.pts"))
for point_file in tqdm(points_files):
    point_cloud = np.loadtxt(point_file)
    if point_cloud.shape[0] < NUM_SAMPLE_POINTS:
        continue

    # Get the file-id of the current point cloud for parsing its
    # labels.
    file_id = point_file.split("/")[-1].split(".")[0]
    label_data, num_labels = {}, 0
    for label in LABELS:
        label_file = os.path.join(labels_dir, label, file_id + ".seg")
        if os.path.exists(label_file):
            label_data[label] = np.loadtxt(label_file).astype("float32")
            num_labels = len(label_data[label])

    # Point clouds having labels will be our training samples.
    try:
        label_map = ["none"] * num_labels
        for label in LABELS:
            for i, data in enumerate(label_data[label]):
                label_map[i] = label if data == 1 else label_map[i]
        label_data = [
            LABELS.index(label) if label != "none" else len(LABELS)
            for label in label_map
        ]
        # Apply one-hot encoding to the dense label representation.
        label_data = keras.utils.to_categorical(label_data, num_classes=len(LABELS) + 1)

        point_clouds.append(point_cloud)
        point_cloud_labels.append(label_data)
        all_labels.append(label_map)
    except KeyError:
        test_point_clouds.append(point_cloud)
100%|██████████████████████████████████████████████████████████████████████| 4045/4045 [01:30<00:00, 44.54it/s] 

接下来,我们看一下我们刚刚生成的内存中数组中的一些示例:

for _ in range(5):
    i = random.randint(0, len(point_clouds) - 1)
    print(f"point_clouds[{
       i}].shape:", point_clouds[0].shape)
    print(f"point_cloud_labels[{
       i}].shape:", point_cloud_labels[0].shape)
    for j in range(5):
        print(
            f"all_labels[{
       i}][{
       j}]:",
            all_labels[i][j],
            f"\tpoint_cloud_labels[{
       i}][{
       j}]:",
            point_cloud_labels[i][j],
            "\n",
        )
point_clouds[333].shape: (2571, 3) point_cloud_labels[333].shape: (2571, 5) all_labels[333][0]: tail point_cloud_labels[333][0]: [0. 0. 1. 0. 0.] 
all_labels[333][1]: wing point_cloud_labels[333][1]: [1. 0. 0. 0. 0.] 
all_labels[333][2]: tail point_cloud_labels[333][2]: [0. 0. 1. 0. 0.] 
all_

http://www.kler.cn/a/562475.html

相关文章:

  • ktransformers 上的 DeepSeek-R1 671B open-webui
  • 7种内外网数据交换方案全解析 哪种安全、高效、合规?
  • LLM之论文阅读——Context Size对RAG的影响
  • pip太慢了怎么办 换源下载
  • 倚光科技:助力玻璃非球面的打样与小批量生产
  • 【uniapp】上传文件流图片
  • 深入理解 MySQL 事务隔离级别:从“读未提交”到“串行化”的全面解析
  • 嵌入式面试八股文·C语言高频面经(一)
  • 【leetcode】二分算法模板总结
  • 深入理解HTTP Basic认证与Java实现
  • 2 Text2SQL 智能报表方案介绍
  • 【Qt】桌面应用开发 ------ 绘图事件和绘图设备 文件操作
  • 软件安全测评报告内容和作用简析,如何获取权威安全测评报告?
  • 3DGS(三维高斯散射)与SLAM技术结合的应用
  • 使用内置命令查看笔记本电池健康状态
  • 【第三天】零基础学习量化基础代码分析-持续更新
  • Unity百游修炼(3)——Tank_Battle(双人对战)详细制作全流程
  • HTML邮件的制作以及可能遇到的问题
  • 【LeetCode20】有效的括号
  • LeetCodeHot100_0x02