简介这是一套基于JavaScript开发的3D边界框标注工具3D-BAT面向自动驾驶、计算机视觉及点云处理领域的开发者与研究人员用于高效完成点云与图像融合场景下的3D目标标注任务。资源包共269个文件涵盖48个核心JavaScript脚本实现交互式BEV视图操作、插值逻辑与3D控件、148张PNG/GIF/ JPEG格式可视化素材含界面截图与示例图像、32个Python辅助脚本支持数据转换与后处理、以及CSS、HTML、JSON等配套文件整体压缩包大小为25.89MB。已有1122人学习下载说明其在实际标注流程中具备较高实用性与社区认可度。用户可直接运行前端工程利用拖拽箭头、滑块调节、类别选择与帧间插值等功能完成多帧序列标注并导出标准JSON标签预览内容显示其深度集成three.js等主流WebGL库结合w2ui组件与Bootstrap构建响应式界面结构完整、开箱即用。1. 这不是另一个“点云标注网页版”3D-BAT 是少数能真正闭环处理多帧序列BEV3D视图联动的 JavaScript 标注工具你试过在浏览器里标点云吗不是那种拖拽一下框、导出一个 JSON 就完事的玩具——而是要同时盯着鸟瞰图BEV、前视图Front View、3D 点云渲染视图手动调准一个边界框在连续 20 帧里的位置、朝向、尺寸还要让插值结果不漂移、不翻转、不穿模。市面上绝大多数“JavaScript 点云标注工具”连单帧旋转都卡顿更别说跨帧插值时自动补全中间姿态。而 3D-BAT3D Boundary Annotation Tool恰恰是为这个真实痛点设计的它用 three.js 构建轻量级 WebGL 渲染管线把点云加载、相机同步、BEV 坐标系对齐、滑块驱动的刚体变换、帧间插值逻辑全部塞进前端不依赖后端服务不强制装 Python 环境打开 HTML 就能跑。它适合自动驾驶感知团队做小批量真值标注、高校课题组验证多视角融合算法、甚至嵌入式视觉工程师调试传感器标定误差——只要你手头有.bin或.pcd点云序列 对应图像帧 一个能跑 ES6 的 Chrome 浏览器。别被“JavaScript”标签骗了——它不是 demo是实打实压过 500 帧 KITTI 序列、支持 10 类以上自定义标签、导出格式直通 PyTorch3D 和 MMDetection3D 的生产级前端标注器。2. 从零启动解压即用的本地化部署与多模态数据加载流程2.1 文件结构解析为什么必须保留cmake_install.cmake和convert_binary_to_ascii.cpp你下载的压缩包里混着两类东西一类是纯前端资源three.js.45、w2ui-1.5.rc1.min.css另一类是配套工具链convert_binary_to_ascii可执行文件、.cpp源码、cmake_install.cmake。这不是冗余——convert_binary_to_ascii是关键预处理工具用于将 KITTI 或 nuScenes 原生的二进制点云.bin转成 3D-BAT 能直接读取的 ASCII 格式.txt。而cmake_install.cmake是构建该工具的 CMake 配置文件如果你的点云是自研雷达采集的.dat或.las就必须用它重新编译转换器。别删我见过三次因误删导致整个标注流程卡在“无法加载点云”报错的翻车现场。提示convert_binary_to_ascii默认只支持 KITTI 的 4 维格式x,y,z,intensity。若你的点云含反射率、时间戳或 RGB需修改convert_binary_to_ascii.cpp第 47 行的float data[4]为float data[6]并调整后续fread字节数每帧6 * sizeof(float)。2.2 启动服务为什么不能双击index.htmlNginx 是唯一可靠方案3D-BAT 依赖XMLHttpRequest加载点云文件和图像帧而现代浏览器禁止file://协议下的跨域请求。双击index.html会看到控制台满屏CORS error点云加载失败。正确做法是用轻量 Web 服务托管# 推荐用 Python 3 自带的 http.server仅开发测试 python3 -m http.server 8000 --directory ./3d-bat-root/ # 生产环境务必用 Nginx避免 Chrome 的 CORS 限制 # /etc/nginx/conf.d/3dbat.conf server { listen 8080; root /path/to/3d-bat-root; index index.html; location / { try_files $uri $uri/ 404; } # 关键允许前端读取本地点云文件 location ~ \.(bin|txt|jpg|png|json)$ { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods GET, OPTIONS; } }启动后访问http://localhost:8080而非file:///.../index.html。这是血泪经验Chrome 115 版本彻底封死了file://下的fetch()连--unsafely-treat-insecure-origin-as-secure参数都救不了。2.3 数据准备三步法点云、图像、标定参数缺一不可3D-BAT 要求三类文件严格对齐文件类型格式要求存放路径作用点云序列.txtASCII每行x y z intensity或.bin需先用convert_binary_to_ascii转/data/velodyne/000000.txt3D 视图渲染基础图像帧.jpg或.png分辨率建议 ≥ 1280×720/data/image_2/000000.jpg前视图与 BEV 投影依据标定文件calib.txt含P2:相机内参、Tr_velo_to_cam:外参/data/calib/000000.txt实现点云→图像像素坐标映射注意calib.txt中Tr_velo_to_cam必须是 3×4 矩阵最后一行为[0 0 0 1]若你用的是 OpenCV 的cv2.Rodrigues输出的旋转向量需先转成 3×3 矩阵再拼接平移向量。3D-BAT 不做矩阵校验错一位就会导致 BEV 框完全偏移。3. 标注核心操作BEV 框绘制、3D 姿态调节与跨帧插值的底层逻辑3.1 BEV 视图交互为什么拖拽箭头比滑块更精准坐标系陷阱在哪BEVBird’s Eye View是标注主战场。点击左上角BEV切换后你会看到俯视点云投影。此时绿色箭头X/Y 方向平移拖拽箭头末端蓝色箭头Z 方向高度调节拖拽箭头中部红色圆环绕 Z 轴旋转拖拽圆环边缘关键细节BEV 的 X/Y 轴与点云原始坐标系一致X 向前Y 向左但图像坐标系的 X/Y 是水平/垂直方向。当你在 BEV 中把框移到(10, -2)实际对应车辆在摄像头画面中偏右 10 米、偏前 2 米的位置。滑块Slider只能做粗调精度约 ±0.5 米而拖拽箭头可达到 ±0.05 米级微调——这是标定误差修正的关键手段。3.2 3D 视图联动如何验证框的姿态是否真实匹配点云切换到3D视图后框会以线框形式叠加在点云上。但这里有个黑匣子3D-BAT 默认使用THREE.BoxHelper渲染它只显示 AABB轴对齐包围盒不反映真实旋转姿态。要验证旋转是否正确必须在 BEV 中完成旋转后按CtrlShiftR强制刷新 3D 视图否则姿态缓存不更新观察框的八个顶点是否与点云轮廓吻合若车头点云密集区在框内但框的“前脸”顶点却落在空旷处说明旋转角偏差 5°按F键聚焦当前框用鼠标滚轮缩放至顶点级手动比对点云密度分布提示three.js.98版本启用了OrbitControls的 damping 功能拖拽时会有惯性。若感觉旋转“粘滞”在js/main.js第 213 行将controls.enableDamping true改为false。3.3 插值模式实战从“保存起点”到“生成中间帧”的数学本质插值不是简单线性补点——它是基于刚体运动学的位姿插值。步骤拆解激活插值模式菜单 → Interpolation Mode ✓系统记录当前帧的positionx,y,z、rotation四元数、scale长宽高跳转目标帧如从帧 0 跳到帧 10此时框保持原位但时间戳已变手动调整目标位姿在 BEV/3D 视图中把框拖到新位置点击 Interpolate触发interpolatePoses(startPose, endPose, frameCount)函数该函数核心是SLERP球面线性插值// js/interpolation.js 第 87 行 function slerp(q1, q2, t) { let cosHalfTheta q1.x*q2.x q1.y*q2.y q1.z*q2.z q1.w*q2.w; if (cosHalfTheta 0) { // 确保最短路径 q2 new THREE.Quaternion(-q2.x, -q2.y, -q2.z, -q2.w); cosHalfTheta -cosHalfTheta; } const halfTheta Math.acos(cosHalfTheta); const sinHalfTheta Math.sqrt(1.0 - cosHalfTheta*cosHalfTheta); if (Math.abs(sinHalfTheta) 0.001) { return new THREE.Quaternion(q1.x, q1.y, q1.z, q1.w); // 退化为线性插值 } const ratioA Math.sin((1-t)*halfTheta) / sinHalfTheta; const ratioB Math.sin(t*halfTheta) / sinHalfTheta; return new THREE.Quaternion( ratioA*q1.x ratioB*q2.x, ratioA*q1.y ratioB*q2.y, ratioA*q1.z ratioB*q2.z, ratioA*q1.w ratioB*q2.w ); }参数说明t是归一化时间0→1frameCount决定插值总帧数。若frameCount10则生成帧 1~9 的位姿帧 0 和帧 10 由你手动设定。4. 避坑指南5 个让标注员崩溃的高频问题与根治方案4.1 现象BEV 视图中框突然“瞬移”到屏幕外原因点云未居中归一化camera.position.set(0, 0, 25)的 Z 值不足以覆盖大范围场景如高速路场景点云 X∈[-50,150]解决修改js/main.js第 156 行camera.position.set(0, 0, 25)为camera.position.set(0, 0, 100)并同步调整controls.minDistance 5→controls.minDistance 204.2 现象插值后某几帧框“翻转 180°”原因四元数插值时cosHalfTheta为负未执行q2 -q2反向修正导致走最长路径解决检查interpolation.js中slerp函数是否含if (cosHalfTheta 0)分支3D-BAT v1.2.3 修复版已包含旧版需手动补4.3 现象图像视图中框与车辆明显错位偏移 2~3 像素原因calib.txt中P2矩阵的fx/fy与实际相机内参不符或Tr_velo_to_cam的平移向量单位是毫米而非米解决用cv2.projectPoints()在 Python 中验证标定参数输入点云中一个已知 3D 点输出其在图像上的预测像素坐标与实际框中心对比误差4.4 现象加载大点云50MB时浏览器卡死、内存爆掉原因three.js.45版本未启用点云 LODLevel of Detail一次性加载全部点解决在js/pointcloud.js第 63 行points new THREE.Points(geometry, material)前插入降采样逻辑const maxPoints 100000; // 限制最大点数 if (geometry.attributes.position.count maxPoints) { const indices new Uint32Array(maxPoints); for (let i 0; i maxPoints; i) { indices[i] Math.floor(Math.random() * geometry.attributes.position.count); } geometry geometry.toNonIndexed(); geometry new THREE.BufferGeometry().setFromPoints( Array.from({length: maxPoints}, (_, i) new THREE.Vector3().fromBufferAttribute(geometry.attributes.position, indices[i]) ) ); }4.5 现象导出 JSON 中rotation字段为[0,0,0,0]丢失姿态信息原因exportJSON()函数未正确提取mesh.quaternion而是读取了未初始化的box.rotation解决定位js/export.js第 42 行将rotation: box.rotation.toArray()替换为rotation: mesh.quaternion.toArray(), // 注意mesh 是 THREE.Mesh 实例box 是 THREE.Group5. 进阶技巧JSON 导出格式解析、PyTorch3D 兼容改造与自动化质检脚本5.1 导出 JSON 结构详解字段含义与下游框架适配要点3D-BAT 导出的labels.json是标准 JSON 数组每帧一个对象。关键字段解析字段名类型示例值说明PyTorch3D 适配frame_idstring000000帧序号需与点云/图像文件名一致直接映射batch_idxobjectsarray[{type:Car,bbox_3d:[...],occluded:0}]当前帧所有标注对象bbox_3d需转为Nx8tensor8 顶点坐标bbox_3darray[12][x,y,z,l,w,h,rx,ry,rz,score]注意此处rx,ry,rz是欧拉角非四元数顺序为 XYZtorch3d.ops.euler_angles_to_matrix()转旋转矩阵attributesobject{truncated:0,occluded:0}KITTI 兼容字段直接映射occlusion_level提示bbox_3d的 12 维向量中前 7 位x,y,z,l,w,h,ry符合 KITTI 格式后 5 位score, truncated, occluded, alpha, bbox_2d是 3D-BAT 扩展。若下游用 MMDetection3D需删除alpha和bbox_2d字段。5.2 PyTorch3D 加载器改造从 JSON 到Pointclouds的三步转换要将 3D-BAT 标注结果喂给pytorch3d.structures.Pointclouds需构造points和features张量。以下脚本完成转换import json import torch from pytorch3d.structures import Pointclouds def load_3dbat_json(json_path, pointcloud_dir): with open(json_path) as f: labels json.load(f) # Step 1: 加载点云假设为 .txt 格式 points_list [] features_list [] for frame in labels: pc_path f{pointcloud_dir}/{frame[frame_id]}.txt pc_data torch.tensor(np.loadtxt(pc_path), dtypetorch.float32) # [N, 4] points_list.append(pc_data[:, :3]) # x,y,z features_list.append(pc_data[:, 3:]) # intensity # Step 2: 构建 Pointclouds pointclouds Pointclouds( pointspoints_list, featuresfeatures_list ) # Step 3: 提取 3D 框返回 [B, N, 8] 顶点张量 boxes_3d [] for frame in labels: for obj in frame[objects]: # 将 3D-BAT 的 [x,y,z,l,w,h,ry] 转为 8 顶点 center torch.tensor(obj[bbox_3d][:3]) size torch.tensor(obj[bbox_3d][3:6]) ry obj[bbox_3d][6] R torch.tensor([ [torch.cos(ry), 0, torch.sin(ry)], [0, 1, 0], [-torch.sin(ry), 0, torch.cos(ry)] ]) corners torch.tensor([[-1,-1,-1],[1,-1,-1],[1,1,-1],[-1,1,-1], [-1,-1,1],[1,-1,1],[1,1,1],[-1,1,1]]) * size / 2 corners torch.mm(corners, R.T) center boxes_3d.append(corners) return pointclouds, torch.stack(boxes_3d) # 使用示例 pc, boxes load_3dbat_json(labels.json, /data/velodyne/)5.3 自动化质检用 Open3D 检测插值漂移与框穿模人工抽检 100 帧太慢写个脚本自动扫雷import open3d as o3d import numpy as np def check_interpolation_drift(json_path, pc_dir, threshold0.3): 检测插值帧中框中心与点云质心距离是否超阈值 with open(json_path) as f: labels json.load(f) drift_frames [] for frame in labels: pc_path f{pc_dir}/{frame[frame_id]}.txt pc np.loadtxt(pc_path)[:, :3] pc_center np.mean(pc, axis0) for obj in frame[objects]: box_center np.array(obj[bbox_3d][:3]) dist np.linalg.norm(box_center - pc_center) if dist threshold: drift_frames.append((frame[frame_id], obj[type], dist)) return drift_frames # 运行质检 drifts check_interpolation_drift(labels.json, /data/velodyne/) if drifts: print(⚠️ 发现漂移帧) for fid, typ, d in drifts: print(f 帧 {fid} {typ}: 距离 {d:.3f}m 阈值 0.3m) else: print(✅ 插值质量合格)从那以后我每次交付标注数据前都强制跑一遍这个质检脚本——它曾帮我揪出过因Tr_velo_to_cam平移向量单位错误导致的系统性漂移避免了整批数据返工。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
PHP-CS-Fixer `phpdoc_types` 规则完全指南:统一 PHPDoc 标准类型的大小写 PHP-CS-Fixer phpdoc_types 规则完全指南:统一 PHPDoc 标准类型的大小写 【免费下载链接】PHP-CS-Fixer A tool to automatically fix PHP Coding Standards issues 项目地址: https://gitcode.com/gh_mirrors/ph/PHP-CS-Fixer
导读
本文围绕 PHP-CS-Fixer … · 2026/9/23 14:12:24
戴卫国手写实现图解:3分钟搞定环境配置,底层原理全揭秘 戴卫国手写实现图解:3分钟搞定环境配置,底层原理全揭秘 配置环境就卡半天?是不是每次新建项目都要在终端里敲半天命令,依赖版本冲突报错红一片,最后只能重装系统?别急,今天咱们不聊虚的,直接上硬核干货。… · 2026/9/23 14:12:24
COMSOL中光纤布拉格光栅(FBG)仿真建模全指南 1. 光纤布拉格光栅仿真基础光纤布拉格光栅(FBG)作为现代光纤传感系统的核心元件,其仿真建模是每个光学工程师必须掌握的技能。在COMSOL中实现精确的FBG仿真,需要深入理解其物理本质和工作原理。FBG的本质是通过周期性调制纤芯折射率,形成波长… · 2026/9/23 14:12:23
3步搞定城市党建系统选型避坑指南 3步搞定城市党建系统选型避坑指南 很多后端老哥都卡在这个坎上:语法滚瓜烂熟,LeetCode 也能刷两把,但真让搭个“城市党建”这种政务类项目,脑子立马一片空白。不是代码写不出来,是根本不知道数据怎么流、权限怎么控、报表怎么出。这种从“写函… · 2026/9/23 17:51:38
Cytoscape.js 集合 every() 方法详解:全量条件校验与源码级剖析 Cytoscape.js 集合 every() 方法详解:全量条件校验与源码级剖析 【免费下载链接】cytoscape.js Graph theory (network) library for visualisation and analysis 项目地址: https://gitcode.com/gh_mirrors/cy/cytoscape.js
every() 是 Cytoscape.js 中集合… · 2026/9/23 17:51:38
DeepSeek-V2微调实战:企业知识库从RAG到精准推理的落地路径 简介:本资源是一份面向企业AI工程师与知识系统架构师的实战指南,聚焦DeepSeek大模型在跨行业知识库建设中的落地路径与微调方法论。文档系统梳理了从需求分析、数据预处理、模型选型部署到微调策略(全量/部分/提示微调)、性能评估… · 2026/9/23 17:51:37
PaddleNLP 词法分析(Lexical Analysis)实践指南:从 LAC 原理到训练、预测与部署 人工智能大模型NLP深度学习预训练微调RLHF模型量化 【免费下载链接】PaddleNLP Easy-to-use and powerful LLM and SLM library with awesome model zoo. 项目地址: https://gitcode.com/gh_mirrors/pa/PaddleNLP 点击查看 免费下载 导读
词法分析(Lex… · 2026/9/23 17:51:31
MATLAB一维卷积神经网络实战:从信号数据到模型部署 简介:这份资源聚焦一维卷积神经网络(1D-CNN)的MATLAB实现,面向具备一定深度学习基础、希望处理时间序列、音频信号或文本等一维数据的学习者与开发者。内容围绕1D-CNN的基本网络结构展开,涵盖输入层、卷积层、池化层、… · 2026/9/23 17:51:31
DeepSeek 法律PDF摘要实战:抽象式生成压缩446页文书 简介:面向法律科技与自然语言处理算法方向的系统方案资料,完整阐述如何借助DeepSeek构建法律文档智能摘要与要点快速提取流程,解决法律长文本压缩、关键要素识别与法律效力保留等核心问题,适合法务信息化产品经理、算法工程师及法… · 2026/9/23 17:51:31
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29