OpenMMlab导出PointPillars模型并用onnxruntime推理

导出onnx文件

通过mmdeploy的tool/deploy.py脚本容易转换得到PointPillars的end2end.onnx模型。
在这里插入图片描述
根据https://github.com/open-mmlab/mmdeploy/blob/main/docs/zh_cn/04-supported-codebases/mmdet3d.md显示,截止目前 mmdet3d 的 voxelize 预处理和后处理未转成 onnx 操作;C++ SDK 也未实现 voxelize 计算。

onnxruntime推理

需要安装mmdetection3d等包:

import torch
import onnxruntime
import numpy as np
from torch.nn import functional as F
from mmdet3d.apis import init_model, inference_detector
from mmcv.ops import nms, nms_rotated
from ops.voxel_module import Voxelization
from ops.iou3d_op import nms_gpuconfig_file = 'pointpillars_hv_secfpn_8xb6-160e_kitti-3d-car.py'
checkpoint_file = 'hv_pointpillars_secfpn_6x8_160e_kitti-3d-car_20220331_134606-d42d15ed.pth'class PointPillars(torch.nn.Module):def __init__(self):super().__init__()self.model = init_model(config_file, checkpoint_file, device='cpu')self.box_code_size = 7self.num_classes = 1self.nms_pre = 100self.max_num = 50self.score_thr = 0.1self.nms_thr = 0.01self.voxel_layer = Voxelization(voxel_size= [0.16, 0.16, 4], point_cloud_range=[0, -39.68, -3, 69.12, 39.68, 1], max_num_points=32, max_voxels=[16000, 40000])self.mlvl_priors = self.model.bbox_head.prior_generator.grid_anchors([torch.Size([248, 216])])self.mlvl_priors = [prior.reshape(-1, self.box_code_size) for prior in self.mlvl_priors]def pre_process(self, x):res_voxels, res_coors, res_num_points = self.voxel_layer(x)return res_voxels, res_coors, res_num_pointsdef xywhr2xyxyr(self, boxes_xywhr):boxes = torch.zeros_like(boxes_xywhr)half_w = boxes_xywhr[..., 2] / 2half_h = boxes_xywhr[..., 3] / 2boxes[..., 0] = boxes_xywhr[..., 0] - half_wboxes[..., 1] = boxes_xywhr[..., 1] - half_hboxes[..., 2] = boxes_xywhr[..., 0] + half_wboxes[..., 3] = boxes_xywhr[..., 1] + half_hboxes[..., 4] = boxes_xywhr[..., 4]return boxesdef box3d_multiclass_nms(self, mlvl_bboxes, mlvl_bboxes_for_nms, mlvl_scores, mlvl_dir_scores):num_classes = mlvl_scores.shape[1] - 1bboxes = []scores = []labels = []dir_scores = []for i in range(0, num_classes):cls_inds = mlvl_scores[:, i] > self.score_thrif not cls_inds.any():continue_scores = mlvl_scores[cls_inds, i]_bboxes_for_nms = mlvl_bboxes_for_nms[cls_inds, :].cuda()keep = torch.zeros(_bboxes_for_nms.size(0), dtype=torch.long)num_out = nms_gpu(_bboxes_for_nms.cuda(), keep, self.nms_thr, _bboxes_for_nms.device.index)selected = keep[:num_out]bboxes.append(mlvl_bboxes[selected])scores.append(_scores[selected])cls_label = mlvl_bboxes.new_full((len(selected), ), i, dtype=torch.long)labels.append(cls_label)dir_scores.append(mlvl_dir_scores[selected])if bboxes:bboxes = torch.cat(bboxes, dim=0)scores = torch.cat(scores, dim=0)labels = torch.cat(labels, dim=0)dir_scores = torch.cat(dir_scores, dim=0)if bboxes.shape[0] > self.max_num:_, inds = scores.sort(descending=True)inds = inds[:self.max_num]bboxes = bboxes[inds, :]labels = labels[inds]scores = scores[inds]dir_scores = dir_scores[inds]else:bboxes = mlvl_scores.new_zeros((0, mlvl_bboxes.size(-1)))scores = mlvl_scores.new_zeros((0, ))labels = mlvl_scores.new_zeros((0, ), dtype=torch.long)dir_scores = mlvl_scores.new_zeros((0, ))return (bboxes, scores, labels, dir_scores)def decode(self, anchors, deltas):xa, ya, za, wa, la, ha, ra = torch.split(anchors, 1, dim=-1)xt, yt, zt, wt, lt, ht, rt = torch.split(deltas, 1, dim=-1)za = za + ha / 2diagonal = torch.sqrt(la**2 + wa**2)xg = xt * diagonal + xayg = yt * diagonal + yazg = zt * ha + zalg = torch.exp(lt) * lawg = torch.exp(wt) * wahg = torch.exp(ht) * harg = rt + razg = zg - hg / 2return torch.cat([xg, yg, zg, wg, lg, hg, rg], dim=-1)def predict_by_feat_single(self, cls_score, bbox_pred, dir_cls_pred):priors = self.mlvl_priors[0]dir_cls_pred = dir_cls_pred.permute(1, 2, 0).reshape(-1, 2)dir_cls_scores = torch.max(dir_cls_pred, dim=-1)[1]cls_score = cls_score.permute(1, 2, 0).reshape(-1, self.num_classes)scores = cls_score.sigmoid()bbox_pred = bbox_pred.permute(1, 2, 0).reshape(-1, self.box_code_size)       max_scores, _ = scores.max(dim=1)_, topk_inds = max_scores.topk(self.nms_pre)    priors = priors[topk_inds, :].cpu()bbox_pred = bbox_pred[topk_inds, :]scores = scores[topk_inds, :]dir_cls_scores = dir_cls_scores[topk_inds]bboxes = self.decode(priors, bbox_pred)mlvl_bboxes_bev =  torch.cat([bboxes[:, 0:2], bboxes[:, 3:5], bboxes[:, 5:6]], dim=1)mlvl_bboxes_for_nms = self.xywhr2xyxyr(mlvl_bboxes_bev)    padding = scores.new_zeros(scores.shape[0], 1)scores = torch.cat([scores, padding], dim=1)       results = self.box3d_multiclass_nms(bboxes, mlvl_bboxes_for_nms, scores, dir_cls_scores)bboxes, scores, labels, dir_scores = resultsif bboxes.shape[0] > 0:   dir_rot = bboxes[..., 6] + np.pi/2 - torch.floor(bboxes[..., 6] + np.pi/2 / np.pi ) * np.pibboxes[..., 6] = (dir_rot - np.pi/2 + np.pi * dir_scores.to(bboxes.dtype))         return bboxes, scores, labelsdef forward(self, res_voxels, res_coors, res_num_points):  voxels, coors, num_points = [], [], []res_coors = F.pad(res_coors, (1, 0), mode='constant', value=0)voxels.append(res_voxels)coors.append(res_coors)num_points.append(res_num_points)voxels = torch.cat(voxels, dim=0)coors = torch.cat(coors, dim=0)num_points = torch.cat(num_points, dim=0)x = self.model.voxel_encoder(voxels, num_points, coors) x = self.model.middle_encoder(x, coors, batch_size=1)         x = self.model.backbone(x)x = self.model.neck(x)  cls_scores, bbox_preds, dir_cls_preds = self.model.bbox_head(x)    return cls_scores[0], bbox_preds[0], dir_cls_preds[0]points = np.fromfile('demo/data/kitti/000008.bin', dtype=np.float32)
points = torch.from_numpy(points.reshape(-1, 4))  voxel_layer = Voxelization(voxel_size= [0.16, 0.16, 4], point_cloud_range=[0, -39.68, -3, 69.12, 39.68, 1], max_num_points=32, max_voxels=[16000, 40000])     
res_voxels, res_coors, res_num_points = voxel_layer(points)
res_coors = torch.cat([torch.zeros([res_coors.shape[0], 1]), res_coors], axis=1)onnx_session = onnxruntime.InferenceSession("../work_dir/onnx/pointpillars/end2end.onnx", providers=['CPUExecutionProvider'])input_name = []
for node in onnx_session.get_inputs():input_name.append(node.name)output_name = []
for node in onnx_session.get_outputs():output_name.append(node.name)inputs = {}
inputs['voxels'] = res_voxels.numpy()
inputs['num_points'] = res_num_points.type(torch.int32).numpy()
inputs['coors'] = res_coors.type(torch.int32).numpy()outputs = onnx_session.run(None, inputs)
cls_score = torch.from_numpy(outputs[0][0])
bbox_pred = torch.from_numpy(outputs[1][0])
dir_cls_pred = torch.from_numpy(outputs[2][0])pointpillars = PointPillars()
result = pointpillars.predict_by_feat_single(cls_score, bbox_pred, dir_cls_pred)
print(result)

其中ops包来自:https://github.com/zhulf0804/PointPillars/tree/main/ops
结果输出:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/604100.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WorkPlus完备的企业级功能堆栈,打造高效的企业移动平台

在如今的数字化时代,企业需要一个完备的功能堆栈来满足复杂的业务需求。WorkPlus作为一个完整的企业级移动平台,拥有完备的企业级功能,如IM、通讯录、内部群、模板群、工作台、权限管控、应用中心、日程管理、邮箱、同事圈、服务号、智能表单…

ROS学习笔记(9)进一步深入了解ROS第三步

0.前提 1. (C)Why did you include the header file of the message file instead of the message file itself?(为包含消息的头文件而不是消息本身?) 回答:msg文件是描述ROS消息字段的文本文件,用于生成不同语言消息…

银行十大主题域

当事人、产品、协议、事件、资产、财务、机构、地域、营销、渠道 便于记忆: 银行是一个企业,同时也是一个机构,涉及企业机构就会有资产,财务的存在,银行有自己的产品(信用卡,黄金,期…

SpringCloud中网关拿到的路径(使用nacos做配置中心)

配置中心 - id: systemuri: lb://systempredicates:- Path=/system/**filters: - StripPrefix=1这里会消去system这一层的请求 网关代码 import org.springframework.cloud.gateway.filter.GatewayFilterChain; import

《微信小程序开发从入门到实战》学习七十四

6.8 文件API 使用文件API可以对用户手机设备中的文件进行一些操作。 为安全考虑,不同小程序间保存的文件是互相隔离的, 小程序外部获取的文件(如从手机中选择的文件)在小程序中也都是以临时文件存在的。 6.8.1 选择文件API 使…

2024.1.7 Spark SQL , DataFrame

目录 一 . SparkSQL简介 二 . Spark SQL与HIVE的异同 三 . DataFrame 1. 创建 DataFrame 2. RDD转换DataFrame 四 . 操作DataFrame SQL方式: DSL方式: 一 . SparkSQL简介 Spark SQL只能处理结构化数据 ,属于Spark框架一个部分 Schema:元数据信息 特点: 融合性 ,统一数…

批量删除文件名的空格,一键清理让文件名中的空格去无踪

我们每天都会创建、下载、重命名很多文件,在文件的重命名过程中,我们会不自觉地在文件名中加入空格,这些看似无害的空格,在某些情况下,却可能引发诸多不便。例如,在某些软件或操作系统中,空格可…

Mac M1 Parallels Debian10 Install Gitlab

安装Debian10 Debian10百度网盘下载链接: https://pan.baidu.com/s/1ovBWIhTpljIVOxEkjJQjkQ?pwd6666 提取码: 6666 –来自百度网盘超级会员v7的分享 # 1.install # 2.localtion: 中国 → 语言: 中文(简体) # 3.网络 默认、自动配置 # 4.主机名域名(随意…

【数据仓库与联机分析处理】数据仓库工具Hive

目录 一、Hive简介 (一)什么是Hive (二)优缺点 (三)Hive架构原理 (四)Hive 和数据库比较 二、MySQL的安装配置 三、Hive的安装配置 1、下载安装包 2、解压并改名 3、配置环…

多时点DID

标准 DID 模型一般针对政策实施时点为同一个时期,且接受干预的状态将一直持续下去,否则 的交互项设置将会严重违背平行趋势的假设,从而导致交互项的估计系数有偏。由于现实世界中很多的政策试点地区和时间都不尽相同,而且也容易发…

unity 游戏开发中傻傻分不清URP、HDRP和SRP

文章目录 **URP (Universal Render Pipeline)**:**HDRP (High Definition Render Pipeline)**:**区别**: Unity的URP(Universal Render Pipeline)和HDRP(High Definition Render Pipeline)都是基于SRP(Scri…

深入了解Snowflake雪花算法:分布式唯一ID生成器

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…

go 切片长度与容量的区别

切片的声明 切片可以看成是数组的引用(实际上切片的底层数据结构确实是数组)。在 Go 中,每个数组的大小是固定的,不能随意改变大小,切片可以为数组提供动态增长和缩小的需求,但其本身并不存储任何数据。 …

安全测试之SSRF请求伪造

前言 SSRF漏洞是一种在未能获取服务器权限时,利用服务器漏洞,由攻击者构造请求,服务器端发起请求的安全漏洞,攻击者可以利用该漏洞诱使服务器端应用程序向攻击者选择的任意域发出HTTP请求。 很多Web应用都提供了从其他的服务器上…

Stable Diffusion 系列教程 - 6 Dreambooth及训练

Stable-Diffusion、Imagen等文生图大模型已经具备了强大的生成能力,假设我们的Prompt为 [Cyberpunk Style],SD或许能很快画出赛博朋克风格的一幅画。但你作为一个不知名的人,不能奢求SD在训练的时候把你自己想要的风格也加进去吧?…

『C++成长记』日期类的实现

🔥博客主页:小王又困了 📚系列专栏:C 🌟人之为学,不日近则日退 ❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、日期类的实现 📒1.1日期类功能 📒1.2拷贝日期 &#…

自动驾驶代客泊车PAVP功能规范

目录 1. 版本记录......................................................................................... 4 2. 引言................................................................................................ 5 2.1 目的/范围...............…

2023的线上事故复盘总结(OOM,数据库崩溃)持续更新中~

项目场景: 智慧门禁系统,公司研制的一个saas系统,基于Springcloud框架,主要是面向高校对老师学生的通行方式做统一的管理,可通过卡、码、脸等多种方式进出,可实现不同人员进出不同的场所,例如宿…

使用ChatGPT生成i项目需求文档模板

前言 我们在工作中需要编写的技术文档有多种形式,包括Word、Excel、PDF及一些在线形式。我们可以借助ChatGPT生成文本,然而,它不能直接生成Word、Excel、PDF等格式的文档。因此,我们需要利用其他工具来帮助我们生成一些模板&…

三、计算机理论-关系数据库-数据库的完整性与安全性,事务管理、并发控制、数据库的备份与恢复

数据库完整性 完整性是为了防止合法用户在使用数据库时向数据库中加入不符合语义的数据 实体完整性 实体完整性约束时通过主码的定义来实现的,使用PRIMARY KEY来定义,对于单个属性的主码可以使用列级完整性约束,若主码是一个属性组&#xff…