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

使用 PointNet 进行点云分段

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

(i) 此示例使用 Keras 3

 在 Colab 中查看 

 GitHub 源


介绍

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

在此示例中,我们演示了 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_
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空云风语

人工智能,深度学习,神经网络

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值