ModelNet数据集下载
ModelNet数据集是一个广泛用于三维形状识别和理解的大规模数据集。该数据集由麻省理工学院(MIT)的计算机科学与人工智能实验室(CSAIL)创建,并在2013年发布。
ModelNet数据集包含了各种不同类别的三维模型。这些模型来自于多个来源,包括Google 3D Warehouse、Trimble 3D Warehouse和部分自定义模型。数据集中的模型涵盖了常见的物体类别,如桌子、椅子、床、沙发、书架、显示器等,总共包含了40个不同的类别。
ModelNet数据集提供了两个版本:ModelNet10和ModelNet40。ModelNet10包含了每个类别约3991个三维模型,而ModelNet40则包含了每个类别约9843个三维模型。每个模型均以OFF格式(包含顶点和面片信息)存储,并且具有统一的尺寸和方向。
你可以在麻省理工的官网上下载数据集
但是我自己在进行下载时出现了点击下载地址没有反应的情况
你可以通过按F12来找到他后台的下载地址
- 先点击1的图标
- 将鼠标挪到2点击这个下载地址
- 你可以从下面找到一个下载网址,你能通过打开这个网址来进行下载
对下载数据的预处理
原始的下载数据
这里以modelNet10为例介绍,一共有十种类别
你可以看到所有的数据都是.off格式
以下是文件的举例,来自官方文档
OFF 8 6 0 -0.500000 -0.500000 0.500000 0.500000 -0.500000 0.500000 -0.500000 0.500000 0.500000 0.500000 0.500000 0.500000 -0.500000 0.500000 -0.500000 0.500000 0.500000 -0.500000 -0.500000 -0.500000 -0.500000 0.500000 -0.500000 -0.500000 4 0 1 3 2 4 2 3 5 4 4 4 5 7 6 4 6 7 1 0 4 1 7 5 3 4 6 0 2 4
OFF为文档的开始 第二行中8 为定点数 ,6 为面数,0为边数(可以被忽略所以这里为0)。
之后的8行为顶点的三维坐标 ,然后6行为面,例如4 0 1 3 2,4为确定该面的点数,0 1 3 2 为顶点的坐标
你也可以直接在cloudcompare中将这个文件打开
例如desk_0001.off
对数据进行处理
我直接将点云数据进行采样以后另存为
注释写的比较详细,希望你能够看懂
import os from tqdm import tqdm import open3d as o3d # 对off点云数据进行采样 def sample_points_from_off(off_file, num_points): # 读取OFF文件 mesh = o3d.io.read_triangle_mesh(off_file) # 将OFF文件转换为点云 point_cloud = mesh.sample_points_uniformly(num_points) return point_cloud # 文件夹路径 path = 'ModelNet10ModelNet10' folder_path =[] # 获取每一个类别的名称 for item in os.listdir(path): if not '.' in item: folder_path.append(os.path.join(path, item)) # 获取文件名 def get_file_name(path): return path.split('\')[-1].split('.')[0] # 遍历所有文件夹 for file in folder_path: # 获得完整的训练集和测试集文件路径 train_file = os.path.join(file, 'train') test_file = os.path.join(file, 'test') # 对训练集和测试集进行处理 for filepath in [train_file, test_file]: # 获取该文件夹下的所有文件名 filenames = os.listdir(filepath) # 处理每个文件(点云) for filename in tqdm(filenames): # 获取点云文件的完整地址 old_path = os.path.join(filepath, filename) # 如果文件名以.开头,则跳过(这里假设以.开头的文件是无效文件) if(filename.startswith('.')): continue # 读取点云数据 point_cloud = sample_points_from_off(old_path, 10000) # 生成新的文件名(将原文件名的扩展名改为.xyz) name = get_file_name(old_path) + '.xyz' # 新的文件的地址 new_path = os.path.join('new'+old_path).replace(get_file_name(old_path) + '.off', name) # 创建新的文件夹(如果不存在) new_folder = os.path.join(*new_path.split('\')[:-1])+'\' os.makedirs(new_folder, exist_ok=True) # 保存新的点云文件 o3d.io.write_point_cloud(new_path, point_cloud)
这是我的文件结构
这里处理后的文件结构,保持了文件的名字和存储结构
这是利用cloudcompare打开的desk_0001.xyz,只存储了点的三维坐标
这是以上程序的多进程版本
由于数据量比较多(如果你还想用在modelnet40上),一下是多进程版本,速度会非常快
import os from tqdm import tqdm import open3d as o3d from concurrent.futures import ProcessPoolExecutor # 对off点云数据进行采样 def sample_points_from_off(off_file, num_points): # 读取OFF文件 mesh = o3d.io.read_triangle_mesh(off_file) # 将OFF文件转换为点云 point_cloud = mesh.sample_points_uniformly(num_points) return point_cloud # 获取文件名 def get_file_name(path): return path.split('\')[-1].split('.')[0] # 定义一个函数,用来处理单个文件 def process_file(filepath): filenames = os.listdir(filepath) for filename in tqdm(filenames): old_path = os.path.join(filepath, filename) # 如果文件名以.开头,则跳过(这里假设以.开头的文件是无效文件) if filename.startswith('.'): continue # 读取点云数据 point_cloud = sample_points_from_off(old_path, 10000) # 生成新的文件名(将原文件名的扩展名改为.xyz) name = os.path.splitext(filename)[0] + '.xyz' # new_path = os.path.join('new', os.path.dirname(old_path), name) # 新的文件的地址 new_path = os.path.join('new'+old_path).replace(get_file_name(old_path) + '.off', name) # 创建新的文件夹(如果不存在) new_folder = os.path.dirname(new_path) os.makedirs(new_folder, exist_ok=True) # 保存新的点云文件 o3d.io.write_point_cloud(new_path, point_cloud) # 遍历文件夹中的文件 def process_files_in_folder(folder_path): with ProcessPoolExecutor() as executor: for file in folder_path: # 对训练集和测试集进行处理 train_file = os.path.join(file, 'train') test_file = os.path.join(file, 'test') # 使用多进程处理每个文件(点云) executor.submit(process_file, train_file) executor.submit(process_file, test_file) if __name__ == '__main__': # 文件夹路径 path = 'ModelNet10ModelNet10' folder_path =[] # 获取每一个类别的名称 for item in os.listdir(path): if not '.' in item: folder_path.append(os.path.join(path, item)) # 运行任务 process_files_in_folder(folder_path)
如果你想运用在modelnet上可能需要一点点更改(目前我还没下载modelnet40数据)