基于ROPNet项目训练modelnet40数据集进行3d点云的配置
项目地址: https://github.com/zhulf0804/ROPNet 在 MVP Registration Challenge (ICCV Workshop 2021)(ICCV Workshop 2021)中获得了第二名。项目可以在win10环境下运行。
论文地址: https://arxiv.org/abs/2107.02583
网络简介: 一种新的深度学习模型,该模型利用具有区别特征的代表性重叠点进行配准,将部分到部分配准转换为部分完全配准。基于pointnet输出的特征设计了一个上下文引导模块,使用一个编码器来提取全局特征来预测点重叠得分。为了更好地找到有代表性的重叠点,使用提取的全局特征进行粗对齐。然后,引入一种变压器来丰富点特征,并基于点重叠得分和特征匹配去除非代表性点。在部分到完全的模式下建立相似度矩阵,最后采用加权支持向量差来估计变换矩阵。
实施效果: 从数据上看ROPNet与RPMNet与保持了断崖式的领先地位
1、运行环境安装
1.1 项目下载
打开https://github.com/zhulf0804/ROPNet,点Download ZIP然后将代码解压到指定目录下即可。
1.2 依赖项安装
在装有pytorch的环境终端,进入ROPNet-master/src目录,执行以下安装命令。如果已经安装了torch 环境和open3d包,则不用再进行安装了
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118pip install open3d
1.3 模型与数据下载
modelnet40数据集 here [435M]
数据集下载后存储为以下路径即可。
官网预训练模型,无。
第三方预训练模型:使用ROPNet项目在modelnet40数据集上训练的模型
2、关键代码
2.1 dataloader
作者所提供的dataloader只能加载https://shapenet.cs.stanford.edu/media/modelnet40_ply_hdf5_2048.zip 数据集,其所返回的tgt_cloud, src_cloud实质上是基于一个点云采样而来的。 其中的self.label2cat, self.cat2label, self.symmetric_labels等对象代码实际上是没有任何作用的。
import copy
import h5py
import math
import numpy as np
import os
import torchfrom torch.utils.data import Dataset
import sysBASE_DIR = os.path.dirname(os.path.abspath(__file__))
ROOR_DIR = os.path.dirname(BASE_DIR)
sys.path.append(ROOR_DIR)
from utils import random_select_points, shift_point_cloud, jitter_point_cloud, \generate_random_rotation_matrix, generate_random_tranlation_vector, \transform, random_crop, shuffle_pc, random_scale_point_cloud, flip_pchalf1 = ['airplane', 'bathtub', 'bed', 'bench', 'bookshelf', 'bottle', 'bowl','car', 'chair', 'cone', 'cup', 'curtain', 'desk', 'door', 'dresser','flower_pot', 'glass_box', 'guitar', 'keyboard', 'lamp']
half1_symmetric = ['bottle', 'bowl', 'cone', 'cup', 'flower_pot', 'lamp']half2 = ['laptop', 'mantel', 'monitor', 'night_stand', 'person', 'piano','plant', 'radio', 'range_hood', 'sink', 'sofa', 'stairs', 'stool','table', 'tent', 'toilet', 'tv_stand', 'vase', 'wardrobe', 'xbox']
half2_symmetric = ['tent', 'vase']class ModelNet40(Dataset):def __init__(self, root, split, npts, p_keep, noise, unseen, ao=False,normal=False):super(ModelNet40, self).__init__()self.single = False # for specific-class visualizationassert split in ['train', 'val', 'test']self.split = splitself.npts = nptsself.p_keep = p_keepself.noise = noiseself.unseen = unseenself.ao = ao # Asymmetric Objectsself.normal = normalself.half = half1 if split in 'train' else half2self.symmetric = half1_symmetric + half2_symmetricself.label2cat, self.cat2label = self.label2category(os.path.join(root, 'shape_names.txt'))self.half_labels = [self.cat2label[cat] for cat in self.half]self.symmetric_labels = [self.cat2label[cat] for cat in self.symmetric]files = [os.path.join(root, 'ply_data_train{}.h5'.format(i))for i in range(5)]if split == 'test':files = [os.path.join(root, 'ply_data_test{}.h5'.format(i))for i in range(2)]self.data, self.labels = self.decode_h5(files)print(f'split: {self.split}, unique_ids: {len(np.unique(self.labels))}')if self.split == 'train':self.Rs = [generate_random_rotation_matrix() for _ in range(len(self.data))]self.ts = [generate_random_tranlation_vector() for _ in range(len(self.data))]def label2category(self, file):with open(file, 'r') as f:label2cat = [category.strip() for category in f.readlines()]cat2label = {label2cat[i]: i for i in range(len(label2cat))}return label2cat, cat2labeldef decode_h5(self, files):points, normal, label = [], [], []for file in files:f = h5py.File(file, 'r')cur_points = f['data'][:].astype(np.float32)cur_normal = f['normal'][:].astype(np.float32)cur_label = f['label'][:].flatten().astype(np.int32)if self.unseen:idx = np.isin(cur_label, self.half_labels)cur_points = cur_points[idx]cur_normal = cur_normal[idx]cur_label = cur_label[idx]if self.ao and self.split in ['val', 'test']:idx = ~np.isin(cur_label, self.symmetric_labels)cur_points = cur_points[idx]cur_normal = cur_normal[idx]cur_label = cur_label[idx]if self.single:idx = np.isin(cur_label, [8])cur_points = cur_points[idx]cur_normal = cur_normal[idx]cur_label = cur_label[idx]points.append(cur_points)normal.append(cur_normal)label.append(cur_label)points = np.concatenate(points, axis=0)normal = np.concatenate(normal, axis=0)data = np.concatenate([points, normal], axis=-1).astype(np.float32)label = np.concatenate(label, axis=0)return data, labeldef compose(self, item, p_keep):tgt_cloud = self.data[item, ...]if self.split != 'train':np.random.seed(item)R, t = generate_random_rotation_matrix(), generate_random_tranlation_vector()else:tgt_cloud = flip_pc(tgt_cloud)R, t = generate_random_rotation_matrix(), generate_random_tranlation_vector()src_cloud = random_crop(copy.deepcopy(tgt_cloud), p_keep=p_keep[0])src_size = math.ceil(self.npts * p_keep[0])tgt_size = self.nptsif len(p_keep) > 1:tgt_cloud = random_crop(copy.deepcopy(tgt_cloud),p_keep=p_keep[1])tgt_size = math.ceil(self.npts * p_keep[1])src_cloud_points = transform(src_cloud[:, :3], R, t)src_cloud_normal = transform(src_cloud[:, 3:], R)src_cloud = np.concatenate([src_cloud_points, src_cloud_normal],axis=-1)src_cloud = random_select_points(src_cloud, m=src_size)tgt_cloud = random_select_points(tgt_cloud, m=tgt_size)if self.split == 'train' or self.noise:src_cloud[:, :3] = jitter_point_cloud(src_cloud[:, :3])tgt_cloud[:, :3] = jitter_point_cloud(tgt_cloud[:, :3])tgt_cloud, src_cloud = shuffle_pc(tgt_cloud), shuffle_pc(src_cloud)return src_cloud, tgt_cloud, R, tdef __getitem__(self, item):src_cloud, tgt_cloud, R, t = self.compose(item=item,p_keep=self.p_keep)if not self.normal:tgt_cloud, src_cloud = tgt_cloud[:, :3], src_cloud[:, :3]return tgt_cloud, src_cloud, R, tdef __len__(self):return len(self.data)
2.2 模型设计
模型设计如下:
2.3 loss设计
其主要包含Init_loss、Refine_loss和Ol_loss。
其中Init_loss是用于计算 预测点 云 0 预测点云_0 预测点云0与目标点云的mse或mae loss,
Refine_loss用于计算 预测点 云 [ 1 : ] 预测点云_{[1:]} 预测点云[1:]与目标点云的加权mae loss
Ol_loss用于计算两个输入点云输出的重叠分数,使两个点云对应点的重叠分数是一样的。
具体实现代码如上:
import math
import torch
import torch.nn as nn
from utils import square_distsdef Init_loss(gt_transformed_src, pred_transformed_src, loss_type='mae'):losses = {}num_iter = 1if loss_type == 'mse':criterion = nn.MSELoss(reduction='mean')for i in range(num_iter):losses['mse_{}'.format(i)] = criterion(pred_transformed_src[i],gt_transformed_src)elif loss_type == 'mae':criterion = nn.L1Loss(reduction='mean')for i in range(num_iter):losses['mae_{}'.format(i)] = criterion(pred_transformed_src[i],gt_transformed_src)else:raise NotImplementedErrortotal_losses = []for k in losses:total_losses.append(losses[k])losses = torch.sum(torch.stack(total_losses), dim=0)return lossesdef Refine_loss(gt_transformed_src, pred_transformed_src, weights=None, loss_type='mae'):losses = {}num_iter = len(pred_transformed_src)for i in range(num_iter):if weights is None:losses['mae_{}'.format(i)] = torch.mean(torch.abs(pred_transformed_src[i] - gt_transformed_src))else:losses['mae_{}'.format(i)] = torch.mean(torch.sum(weights * torch.mean(torch.abs(pred_transformed_src[i] -gt_transformed_src), dim=-1)/ (torch.sum(weights, dim=-1, keepdim=True) + 1e-8), dim=-1))total_losses = []for k in losses:total_losses.append(losses[k])losses = torch.sum(torch.stack(total_losses), dim=0)return lossesdef Ol_loss(x_ol, y_ol, dists):CELoss = nn.CrossEntropyLoss()x_ol_gt = (torch.min(dists, dim=-1)[0] < 0.05 * 0.05).long() # (B, N)y_ol_gt = (torch.min(dists, dim=1)[0] < 0.05 * 0.05).long() # (B, M)x_ol_loss = CELoss(x_ol, x_ol_gt)y_ol_loss = CELoss(y_ol, y_ol_gt)ol_loss = (x_ol_loss + y_ol_loss) / 2return ol_lossdef cal_loss(gt_transformed_src, pred_transformed_src, dists, x_ol, y_ol):losses = {}losses['init'] = Init_loss(gt_transformed_src,pred_transformed_src[0:1])if x_ol is not None:losses['ol'] = Ol_loss(x_ol, y_ol, dists)losses['refine'] = Refine_loss(gt_transformed_src,pred_transformed_src[1:],weights=None)alpha, beta, gamma = 1, 0.1, 1if x_ol is not None:losses['total'] = losses['init'] + beta * losses['ol'] + gamma * losses['refine']else:losses['total'] = losses['init'] + losses['refine']return losses
3、训练与预测
先进入src目录,并将modelnet40_ply_hdf5_2048.zip解压在src目录下
3.1 训练
训练命令及训练输出如下所示
python train.py --root modelnet40_ply_hdf5_2048/ --noise --unseen
python
在训练过程中会在work_dirs\models\checkpoints目录下生成两个模型文件
3.2 验证
训练命令及训练输出如下所示
python eval.py --root modelnet40_ply_hdf5_2048/ --unseen --noise --cuda --checkpoint work_dirs/models/checkpoints/min_rot_error.pth
3.3 测试
测试训练数据的命令如下
python vis.py --root modelnet40_ply_hdf5_2048/ --unseen --noise --checkpoint work_dirs/models/checkpoints/min_rot_error.pth
具体配准效果如下所示,其中绿色点云为输入点云,红色点云为参考点云,蓝色点云为配准后的点云。可以看到蓝色点云基本与红色点云重合,可以确定其配准效果十分完好。
3.4 处理自己的数据集
基于该项目训练并处理自己数据的教程后续会给出。
相关文章:
基于ROPNet项目训练modelnet40数据集进行3d点云的配置
项目地址: https://github.com/zhulf0804/ROPNet 在 MVP Registration Challenge (ICCV Workshop 2021)(ICCV Workshop 2021)中获得了第二名。项目可以在win10环境下运行。 论文地址: https://arxiv.org/abs/2107.02583 网络简介…...
力扣215. 数组中的第K个最大元素
堆排序 前言 面试中著名的 TopK 排序;常见的解法有冒泡排序、堆排序;更深入的思路可以参考:拜托,面试别再问我TopK了!!!使用了堆排序的算法,关于堆可以参考:堆数据结构的…...
轻量封装WebGPU渲染系统示例<40>- 多层材质的Mask混合(源码)
当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/rendering/src/voxgpu/sample/MaskTextureEffect.ts 当前示例运行效果: 两层材质效果: 三层材质效果: 此示例基于此渲染系统实现,当前示例TypeScript源码如下: export c…...
程序员的实用网站导航与推荐
当你遇到问题时 Stack Overflow:订阅他们的每周新闻和任何你感兴趣的主题Google:全球最大搜索引擎必应:在你无法使用Google的时候CSDN:聊胜于无AI导航一号AI导航二号 新闻篇 OSCHINA:中文开源技术交流社区 针对初学…...
上午面了个腾讯拿 38K 出来的,让我见识到了基础的天花板
今年的校招基本已经进入大规模的开奖季了,很多小伙伴收获不错,拿到了心仪的 offer。 各大论坛和社区里也看见不少小伙伴慷慨地分享了常见的面试题和八股文,为此咱这里也统一做一次大整理和大归类,这也算是划重点了。 俗话说得好…...
【halcon】C# halcon 内存暴增
1 读取图片需要及时手动释放 一个6M的图片通过halcon进行加载,大约会消耗200M的内存,如果等待GC回收,而你又在不停的读取图片,你的内存占用,将在短时间内飙升。 2 halcon控件显示图片需要清空。 /// <summary>…...
LeetCode130. Surrounded Regions
文章目录 一、题目二、题解 一、题目 Given an m x n matrix board containing ‘X’ and ‘O’, capture all regions that are 4-directionally surrounded by ‘X’. A region is captured by flipping all O’s into X’s in that surrounded region. Example 1: Input…...
【实战教程】PHP如何轻松对接腾讯云COS,实现文件上传下载?
腾讯云提供了一系列丰富的云服务,其中包括对象存储(Cloud Object Storage,简称COS),它是一种高可靠性、可扩展性强的云存储服务。本文将介绍如何使用PHP对接腾讯云COS存储服务,实现文件的上传和下载功能。 …...
pytorch学习10-网络模型的保存和加载
系列文章目录 pytorch学习1-数据加载以及Tensorboard可视化工具pytorch学习2-Transforms主要方法使用pytorch学习3-torchvisin和Dataloader的使用pytorch学习4-简易卷积实现pytorch学习5-最大池化层的使用pytorch学习6-非线性变换(ReLU和sigmoid)pytorc…...
SQL Server 2016(分离和附加数据库)
1、实验环境。 基于上一个实验《SQL Server(创建数据库)》 2、需求描述。 class数据库的数据文件和事务日志文件都位于C:\db_class目录下。现在需要把class数据库的数据文件和事务日志文件分开存放,数据文件class.mdf存放于原位置࿰…...
用友U8 Cloud RegisterServlet SQL注入漏洞复现
0x01 产品简介 用友U8 Cloud是用友推出的新一代云ERP,主要聚焦成长型、创新型企业,提供企业级云ERP整体解决方案。 0x02 漏洞概述 用友U8 Cloud RegisterServlet接口处存在SQL注入漏洞,未授权的攻击者可通过此漏洞获取数据库权限,从而盗取用户数据,造成用户信息泄露。 …...
coding创建远程分支。并拉取远程新分支+推送代码
进入coding ----项目----代码仓库---点击 下拉之后查看全部----创建分支 创建分支之后执行下面命令 git branch -a // 查看所有分支 这个时候发现自己创建的分支没有显示这是因为自己在远程创建了分支但是本地还没有分支 执行 git fetch命令 用于从远程仓库获取最新的提交…...
坚鹏:中国工商银行内蒙古分行数字化转型发展现状与成功案例培训
中国工商银行围绕“数字生态、数字资产、数字技术、数字基建、数字基因”五维布局,深入推进数字化转型,加快形成体系化、生态化实施路径,促进科技与业务加速融合,以“数字工行”建设推动“GBC”(政务、企业、个人&…...
AIGC发展史
1 AIGC概况 1.1 AIGC定义 AIGC(AI Generated Content)是指利用人工智能技术生成的内容。它也被认为是继PGC,UGC之后的新型内容生产方式,AI绘画、AI写作等都属于AIGC的具体形式。2022年AIGC发展速度惊人,迭代速度更是呈现指数级发…...
面试题库之JAVA基础篇(二)
String 只读字符串。每次操作会隐式的在内存中new一个跟原字符串一样的StringBuilder对象,然后append号后面的字符串。 StringBuilder 可变字符串对象。线程不安全。 StringBuffer 可变字符串对象。线程安全。 数组 一种线性数据结构,使用连续的…...
[Rust] 可迭代类型, 迭代器, 如何正确的创建自定义可迭代类型
在 Rust 中, for 语句的执行依赖于类型对于 IntoIterator 的实现, 如果某类型实现了这个 trait, 那么它就可以直接使用 for 进行循环. 直接实现 在 Rust 中, 如果一个类型实现了 Iterator, 那么它会被同时实现 IntoIterator, 具体逻辑是返回自身, 因为自身就是迭代器. 但是如…...
MySQL中,text,mediumtext, 和 longtext字符类型
需求 由于项目需要,需要在mysql数据库,储存长文本,长文本格式可能为markdown也可能为html。 思路 测试存入html时,字符类型为varcar 255。很明显字符长度达不到要求。数据库抛错,修改字符类型 解决方案 将原本的字…...
网页开发 JS基础
目录 JS概述 基本语法 数据类型内置方法 DOM对象 查找标签 绑定事件 操作标签 jQuery 查找标签 绑定事件 操作标签 Ajax请求 数据接口 前后端分离 ajax的使用 JS概述 一门弱类型的编程语言,属于基于对象和基于原型的脚本语言. 1 直接编写<script>console…...
如何在财税行业查找批量客户?
现在市场上代记账公司也不算少,做过这行的都知道,最初呢行业竞争不强,都是靠地推、老客户转介绍,或者长期以往的蹲守各个地区的工商注册服务中心,找那些才注册企业的老板或者创业者。但是,随着市场经济的发…...
IntelliJ IDEA详细完整安装教程
IntelliJ IDEA 是一款强大的Java集成开发环境,以下是安装和使用教程: 1. 下载IntelliJ IDEA:访问JetBrains官网(jetbrains.com),点击“Download”按钮,选择适合自己操作系统的版本进行下载。 2.…...
【.NET Core】Linq查询运算符(一)
【.NET Core】Linq查询运算符(一) 文章目录 【.NET Core】Linq查询运算符(一)一、概述二、筛选数据三、投影运算3.1 Select 3.2 SelectMany3.3 Zip3.4 Select 与 SelectMany 四、Set(设置)运算4.1 Distinct…...
Python sorted函数及用法以及如何用json模块存储数据
Python sorted函数及用法 sorted() 函数与 reversed() 函数类似,该函数接收一个可迭代对象作为参数,返回一个对元素排序的列表。 在交互式解释器中测试该函数,可以看到如下运行过程: >>> a [20, 30, -1.2, 3.5, 90, 3.…...
使用opencv将sRGB格式的图片转换为BT.2020格式【sRGB】【BT.2020】
将sRGB格式的图片转换为BT.2020格式涉及到两个步骤:首先将sRGB转换到线性RGB,然后将线性RGB转换到BT.2020。这是因为sRGB图像通常使用伽马校正,而BT.2020工作在线性色彩空间中。 从sRGB到线性RGB:sRGB图像首先需要进行伽马校正解码…...
聊天注意事项
聊天成功的核心就是双方都能舒服 有些人不会聊天是缺乏引导性 聊天聊两句话就没了 聊天要把话题引导向对方 从倾诉者变为倾听者 才能不断交流 沟通不是一个人的独角戏 每个人都渴望被理解 要注意倾听别人说的话 不要只顾自己说一大堆,别人都瞌睡了 不要查户口式问…...
12.5 作业
1, 以下是一个简单的比喻,将多态概念与生活中的实际情况相联系: 比喻:动物园的讲解员和动物表演 想象一下你去了一家动物园,看到了许多不同种类的动物,如狮子、大象、猴子等。现在,动物园里有…...
深入理解指针3
hello,各位小伙伴,本篇文章跟大家一起继续深入学习指针,感谢大家对我上一篇的支持,如有什么问题,还请多多指教 如果本篇文章对你有帮助,还请各位点点赞!!! 话不多说&am…...
大数据环境下在线考试系统安全策略研究
摘 要 随着云计算、物联网、电子商务、企业信息化等的飞速发展,以及智能终端和各种检测、感应设备的普及和建设,全球逐渐进入信息化、网络化,由此产生了指数爆炸般的数据增长,一个大规模生产、分享和应用的数据的时代正在开启&am…...
Python中程序的异常处理
Python程序一般对输入有一定要求,担当实际输入不满足程序要求时,可能会产生程序的运行错误。Python语言使用的保留太容易try和except进行异常处理! try: 语句块1 except: 语句块2 语句块1是正常执行的程序内容,当这个语句块发生异…...
有趣的代码——有故事背景的程序设计3
这篇文章再和大家分享一些有“背景”的程序设计,希望能够让大家学到知识的同时,对编程学习更感兴趣,更能在这条路上坚定地走下去。 目录 1.幻方问题 2.用函数打印九九乘法表 3.鸡兔同笼问题 4.字数统计 5.简单选择排序 1.幻方问题 幻方又…...
聚观早报 |国行PS5轻薄版开售;岚图汽车11月交付7006辆
【聚观365】12月2日消息 国行PS5轻薄版开售 岚图汽车11月交付7006辆 比亚迪推出12月限时优惠 特斯拉正式交付首批Cybertruck 昆仑万维发布「天工 SkyAgents」平台 国行PS5轻薄版开售 索尼最新的PlayStation5主机(CFI-2000型号组-轻薄版)国行版本正…...
网站 keyword title 字数/成品短视频网站源码搭建
1.java当中的四种引用 强引用,软引用,弱引用,虚引用。不同的引用类型主要体现在GC上: 强引用:如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛…...
阿里云ecs 怎么做网站/百度搜索引擎工作原理
2019独角兽企业重金招聘Python工程师标准>>> 第一步:安装Git 第二步:在自己的工程目录下右键鼠标 选择 Git Bash Here 执行命令 git init 来创建一个本地代码仓库 执行命令 git add . 来把所有文件添加到仓库 执行命令 git commit -m "f…...
wordpress格式/网络营销推广
yield,可以使线程放手一下CPU。然后再抓!放一下手,就可以让后面的线程先上了CPU。 例子: public class TestYield {public static void main(String[] args) {MyThread3 t1 new MyThread3("t1");MyThread3 t2 new MyThread3("…...
网站套利怎么做/中国十大关键词
题库来源:安全生产模拟考试一点通公众号小程序 安全生产模拟考试一点通:P气瓶充装考试题考前必练!安全生产模拟考试一点通每个月更新P气瓶充装模拟考试题目及答案!多做几遍,其实通过P气瓶充装证考试很简单。 1、【多选…...
个人网站后台模板/成都全网营销推广
安装:在官网https://jenkins.io/ 下载安装包安装完成后,命令行进入安装目录下替换镜像源:打开C:\Users\xxx.jenkins\hudson.model.UpdateCenter.xml文件,将 url 中的 https://updates.jenkins.io/update-center.json 更改为 https…...
网站备案有期限吗/百度知道合伙人答题兼职
2019独角兽企业重金招聘Python工程师标准>>> 参考链接: http://blog.coinidea.com/web%E5%BC%80%E5%8F%91/nodejs-1131.html 由于nodejs是非阻塞单进程单线程的,一旦nodejs抛出异常,整个服务就会停掉。服务将会非常不稳定。 解决方…...