恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
3D-BAT:轻量级多模态点云图像协同标注工具
首页
资讯中心
/
3D-BAT:轻量级多模态点云图像协同标注工具
3D-BAT:轻量级多模态点云图像协同标注工具
发布时间:2026/9/15 6:25:10
简介这是一套基于JavaScript开发的3D边界框标注工具3D-BAT面向自动驾驶、计算机视觉及点云处理领域的开发者与研究人员用于高效完成点云与图像协同的3D目标标注任务。资源包共269个文件包含48个核心JavaScript脚本支撑三维渲染与交互逻辑、148张PNG图像含界面截图与示例数据、32个Python脚本辅助数据转换与后处理、9个CSS样式文件及5个JSON配置/输出模板整体压缩包大小为25.89MB结构完整、开箱即用。已有1122人学习下载体现其在实际标注流程中的实用价值。用户可直接部署运行支持鸟瞰图BEV中拖拽调整3D框、五类目标汽车/行人/骑车人/摩托车/卡车快速分类、跨帧插值标注并导出标准JSON标签文件预览内容显示集成three.js、jQuery UI及w2ui等成熟前端库具备良好的可视化与交互基础。1. 3D-BAT 不是“点云版 LabelMe”而是专为多模态对齐设计的轻量级标注工作流当你在自动驾驶感知训练、工业零件三维检测或遥感地物识别项目中手头同时有激光雷达采集的.pcd点云和对应视角的.jpg图像时传统工具立刻暴露短板LabelMe 只能标图CloudCompare 只能看点云而二者坐标系不统一、时间戳未对齐、标注结果无法跨模态复用。3D-BAT3D Boundary Annotation Tool正是为解决这一断层而生——它不是把点云和图像简单并排显示而是基于相机内参、外参与点云空间变换矩阵在浏览器中实时构建可交互的三维场景并将二维图像上的矩形框、多边形标注自动反向投影为三维空间中的 Oriented Bounding BoxOBB同时支持手动微调旋转角、尺寸与中心偏移。整个流程完全运行于前端依赖 three.js 渲染核心无需 GPU 服务端推理适合本地快速验证、小团队协作标注、教学演示及嵌入已有 Web 工程。如果你正在用 PCL 做点云预处理、用 OpenCV 校准相机、用 PyTorch 训练 BEVFormer 或 PointPillars 模型那么 3D-BAT 的输出格式JSON PCD JPG 三元组可直接喂入数据加载器跳过繁琐的手动配准与格式转换。2. 用 three.js 构建双视图同步渲染引擎点云与图像的空间对齐原理与实现3D-BAT 的核心能力并非来自复杂算法而在于对几何关系的精确建模与实时可视化。其底层依赖 three.js 构建双通道渲染管线左侧为OrthographicCamera投影的点云三维视图右侧为PerspectiveCamera模拟真实相机的图像平面。二者通过共享同一套世界坐标系World Coordinate System实现刚体对齐关键在于建立点云坐标系LiDAR Frame到图像像素坐标系Image Plane的完整映射链。2.1 坐标系转换链从 PCD 到像素坐标的四步映射整个转换过程包含四个确定性变换每一步都需用户在初始化阶段提供或校准步骤变换类型数学表示输入/输出配置来源1点云本体坐标 → 车体坐标T_lidar_to_vehicle4×4 齐次矩阵.yaml标定文件或 UI 手动输入2车体坐标 → 相机坐标T_vehicle_to_camera4×4 齐次矩阵多传感器联合标定结果3相机坐标 → 归一化图像平面K内参矩阵3×3 矩阵fx, fy, cx, cy来自相机标定4归一化平面 → 像素坐标x u, y v整数坐标three.jsRaycaster逆推提示3D-BAT 不内置标定功能但提供calibration.json模板字段要求填入rotation,translation,intrinsic三组参数。若缺失第 1–2 步矩阵工具会默认使用单位矩阵导致点云漂移若K中cx/cy错误图像框将整体偏移。实际部署前必须用 OpenCVcv2.calibrateCamera()或 ROScamera_info主题验证。2.2 three.js 中的双视图同步机制Raycaster 与 Projector 协同工作3D-BAT 在 three.js 中创建两个独立Scene实例但共享同一套Object3D树结构。所有标注对象如Box3、LineSegments均以世界坐标存储而非绑定于某视图。当用户在图像侧拖拽矩形框时系统执行以下操作// 图像侧鼠标拖拽结束生成二维框 const rect2D new THREE.Box2(new THREE.Vector2(x1, y1), new THREE.Vector2(x2, y2)); // 1. 将图像像素范围反向映射为相机空间射线 const raycaster new THREE.Raycaster(); raycaster.setFromCamera( new THREE.Vector2((x1x2)/2, (y1y2)/2), // 中心点 cameraImage // 图像侧 PerspectiveCamera ); // 2. 获取射线与点云包围盒的交点近似中心 const intersects raycaster.intersectObjects(pointCloudGroup); if (intersects.length 0) { const center3D intersects[0].point.clone(); // 得到世界坐标系下的中心 // 3. 根据框宽高比估算三维尺寸需结合深度图或点云密度 const depth center3D.z; // 假设 Z 轴朝前 const width3D (x2 - x1) * depth / fx; const height3D (y2 - y1) * depth / fy; // 4. 构建 Oriented Bounding Box 并添加到三维场景 const box3D new THREE.Box3(); box3D.setFromCenterAndSize(center3D, new THREE.Vector3(width3D, height3D, 1.5)); scene3D.add(box3DHelper(box3D)); // 可视化辅助 }这段代码的关键在于不依赖深度图而是利用已知内参fx/fy和估算深度z进行尺度反推。对于无深度信息的.pcd文件3D-BAT 默认取点云中该区域最近点的z值作为depth若加载了.npy深度图则优先读取对应(u,v)像素值。2.3 点云渲染优化PCD 解析与 LOD 分级策略原始.pcd文件常达百 MB直接加载会导致浏览器卡顿。3D-BAT 采用两级优化解析层使用pcd-parser库非官方 PCL纯 JS 实现解析 ASCII/二进制 PCD跳过FIELDS中非x y z intensity字段将点数据转为Float32Array渲染层启用 three.jsPointsMaterial的sizeAttenuation: true并根据相机距离动态调整点大小对超过 50 万点的点云启动Octree分块剔除three-octree插件仅渲染视锥体内点。# 典型 PCD 文件头示例3D-BAT 仅解析前 4 行关键字段 # VERSION 0.7 # FIELDS x y z intensity # SIZE 4 4 4 4 # TYPE F F F U # COUNT 1 1 1 1 # WIDTH 124567 # HEIGHT 1 # POINTS 124567 # DATA binary注意若 PCD 含rgb字段3D-BAT 会自动提取r/g/b并映射为vertexColor若含label字段如 SemanticKITTI 格式则支持按语义类别着色需在config.js中开启enableSemanticColoring: true。3. JavaScript 标注逻辑实现从鼠标事件到 JSON 输出的全链路代码解析3D-BAT 的标注行为全部由原生 JavaScript 控制不依赖任何框架React/Vue便于嵌入现有系统。其核心逻辑围绕mouseDown→mouseMove→mouseUp事件流展开并通过状态机管理当前标注模式2D Box / 3D OBB / Polyline / Delete。3.1 标注状态机与 DOM 事件绑定工具在初始化时注册全局事件监听器但仅在激活对应模式时响应// main.js 中的状态机定义 const ANNOTATION_MODES { NONE: 0, DRAW_2D_BOX: 1, DRAW_3D_OBB: 2, EDIT_VERTEX: 3, DELETE: 4 }; let currentMode ANNOTATION_MODES.NONE; let isDrawing false; let startMousePos { x: 0, y: 0 }; canvasImage.addEventListener(mousedown, (e) { if (currentMode ANNOTATION_MODES.DRAW_2D_BOX) { isDrawing true; startMousePos getMousePosition(e, canvasImage); } }); canvasImage.addEventListener(mousemove, (e) { if (isDrawing currentMode ANNOTATION_MODES.DRAW_2D_BOX) { const endPos getMousePosition(e, canvasImage); update2DBox(startMousePos, endPos); // 实时绘制虚线框 } }); canvasImage.addEventListener(mouseup, (e) { if (isDrawing currentMode ANNOTATION_MODES.DRAW_2D_BOX) { const endPos getMousePosition(e, canvasImage); commit2DBox(startMousePos, endPos); // 提交并生成 3D OBB isDrawing false; } });getMousePosition()函数负责将屏幕坐标转换为 canvas 内部坐标并适配高清屏devicePixelRatiofunction getMousePosition(e, canvas) { const rect canvas.getBoundingClientRect(); return { x: ((e.clientX - rect.left) * (canvas.width / rect.width)), y: ((e.clientY - rect.top) * (canvas.height / rect.height)) }; }3.2 3D OBB 数据结构与 JSON 序列化规范每次提交标注后3D-BAT 生成一个标准 JSON 对象严格遵循自动驾驶通用标注协议类似 KITTI 3D label 格式但扩展为 JSON{ frame_id: 000123, timestamp: 1672531200.123, objects: [ { id: car_001, type: Car, truncated: 0.0, occluded: 0, alpha: -0.23, bbox_2d: [124.5, 89.2, 210.7, 178.4], dimensions: [4.5, 1.8, 1.6], location: [12.3, -1.2, 45.6], rotation_y: 0.87, score: 0.92, attributes: { visibility: full, motion_state: static } } ], calibration: { K: [718.856, 0.0, 607.1928, 0.0, 718.856, 185.2157, 0.0, 0.0, 1.0], R0_rect: [0.9999, 0.0012, -0.0045, -0.0012, 0.9999, 0.0021, 0.0045, -0.0021, 0.9999], Tr_velo_to_cam: [0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0] } }其中bbox_2d为[x_min, y_min, x_max, y_max]location为(x, y, z)世界坐标非相机坐标rotation_y为绕 Y 轴的弧度角-π 到 π。该 JSON 可直接被kitti_dataset.py或nuscenes-devkit加载。3.3 关键参数配置表config.js中可调项说明3D-BAT 通过config.js控制行为边界以下是生产环境必调的 7 个参数参数名类型默认值说明修改建议maxPointsToRendernumber200000渲染点云最大点数超过此值自动降采样调试时可设为50000加速defaultOBBHeightnumber1.7新建 OBB 默认高度米轿车设1.5卡车设2.8snapToGridbooleantrue是否启用网格吸附开启后顶点移动步长为0.1m提升精度showIntensityAsColorbooleantrue是否用 intensity 值着色点云夜间场景建议关闭改用rgbautoSaveIntervalnumber30000自动保存间隔毫秒设为0关闭自动保存避免频繁写磁盘enableUndoRedobooleantrue是否启用 CtrlZ / CtrlY大型标注任务建议开启exportFormatstringjson导出格式json/kitti/nuscenes与下游训练框架匹配提示exportFormat: kitti会生成.txt文件每行格式为Car -1 -1 0.0 124.5 89.2 210.7 178.4 1.60 1.80 4.50 12.30 -1.20 45.60 0.87与 KITTI 官方格式完全兼容。4. 本地部署与 HBuilder 配置零依赖运行 3D-BAT 的最小化工程实践3D-BAT 本质是一个静态 Web 应用无需 Node.js 后端或 Webpack 构建。最简部署方式是直接用浏览器打开index.html但为保障开发体验与跨平台兼容性推荐使用 HBuilder XDCloud 官方 IDE进行本地托管与调试。4.1 HBuilder X 中的 HTML/CSS/JavaScript 项目结构在 HBuilder X 中新建「普通 Web 项目」目录结构如下3d-bat/ ├── index.html # 主入口含 canvas idcanvas-image 与 div idviewer-3d ├── js/ │ ├── main.js # 全局逻辑、事件绑定、状态机 │ ├── pcd-loader.js # PCD 解析器基于 pcd-parser │ ├── three-ext.js # three.js 扩展OBB 辅助线、点云着色器 │ └── export.js # JSON/KITTI 格式导出逻辑 ├── css/ │ └── style.css # 响应式布局、按钮样式、标注框动画 ├── assets/ │ ├── sample.pcd # 示例点云 │ └── sample.jpg # 对应图像 └── config.js # 用户可编辑的运行时参数注意HBuilder X 内置 Web 服务器CtrlR运行自动处理跨域请求。若直接双击index.html打开Chrome 会因file://协议禁止fetch(./assets/sample.pcd)必须通过http://127.0.0.1:8080/访问。4.2 关键 CSS 布局技巧双视图等宽自适应与标注框视觉反馈style.css中的核心布局采用 CSS Grid确保图像与点云视图严格等宽并在小屏设备上堆叠#app-container { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; height: calc(100vh - 64px); } #canvas-image, #viewer-3d { width: 100%; height: 100%; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.1); } /* 小屏适配 */ media (max-width: 768px) { #app-container { grid-template-columns: 1fr; } } /* 标注框样式2D */ .annotation-box { position: absolute; border: 2px solid #409EFF; background: rgba(64, 158, 239, 0.15); pointer-events: none; transition: all 0.1s ease; } .annotation-box.active { border-color: #67C23A; box-shadow: 0 0 0 2px rgba(103, 194, 58, 0.3); }该 CSS 保证#canvas-image与#viewer-3d始终等宽且随窗口缩放自适应标注框带半透明填充与柔和阴影active状态时绿色高亮符合人机交互直觉移动端下自动切换为单列布局避免水平滚动。4.3 调试常见报错与修复路径3D-BAT 在 HBuilder X 中运行时90% 的报错源于资源路径或 three.js 版本冲突。以下是高频问题与解决方案报错信息根本原因修复命令/操作Uncaught TypeError: Cannot read property x of undefinedpcd-parser未正确解析WIDTH/HEIGHT导致点数组为空检查 PCD 文件头WIDTH是否为整数DATA ascii后是否有多余空行THREE.WebGLRenderer: Context lost.浏览器显存不足尤其 Chrome在chrome://flags中禁用#ignore-gpu-blacklist或降低maxPointsToRenderFailed to load resource: net::ERR_FILE_NOT_FOUNDfetch(./assets/sample.pcd)路径错误确认assets/与index.html同级HBuilder X 中右键「在浏览器中运行」而非双击Uncaught ReferenceError: THREE is not definedthree.js未正确引入或版本不兼容使用three0.152.23D-BAT 测试版本CDN 地址https://cdn.jsdelivr.net/npm/three0.152.2/build/three.min.jsCannot set property color of undefinedPointsMaterial初始化时未传vertexColors: true在pcd-loader.js中检查material new THREE.PointsMaterial({ vertexColors: true, size: 0.02 });提示若需在 HBuilder X 中启用 ESLint可在.eslintrc.js中添加globals: { THREE: true, PCDBuffer: true }避免误报THREE未定义。5. 进阶技巧批量处理与自定义标注属性注入3D-BAT 的设计哲学是「够用即止」但面对量产级标注需求如单日处理 500 帧需借助脚本自动化补足能力。以下三个技巧可显著提升效率且全部基于原生 JavaScript 实现无需修改源码。5.1 批量加载帧序列用FileReader读取文件夹内 PCDJPG 对浏览器原生不支持读取文件夹但可通过input typefile webkitdirectory触发多文件选择。3D-BAT 扩展batchLoader.js实现自动配对document.getElementById(batch-input).addEventListener(change, (e) { const files Array.from(e.target.files); const pcdFiles files.filter(f f.name.endsWith(.pcd)); const jpgFiles files.filter(f f.name.endsWith(.jpg) || f.name.endsWith(.png)); // 按文件名前缀匹配如 000123.pcd ↔ 000123.jpg const pairs pcdFiles.map(pcd { const baseName pcd.name.replace(/\.pcd$/, ); const jpg jpgFiles.find(j j.name.startsWith(baseName)); return { pcd, jpg }; }).filter(pair pair.jpg); // 逐帧加载加防抖避免阻塞 UI let loadIndex 0; function loadNext() { if (loadIndex pairs.length) return; const { pcd, jpg } pairs[loadIndex]; loadFrame(pcd, jpg); // 调用原有加载函数 loadIndex; setTimeout(loadNext, 500); // 间隔 500ms } loadNext(); });该方案支持拖入整个dataset/文件夹自动识别000001.pcd000001.jpg组合无需手动重命名。5.2 注入自定义属性通过config.js扩展attributes字段config.js支持customAttributes配置允许为每类物体预设业务字段// config.js customAttributes: { Car: [license_plate, color, direction], Pedestrian: [age_group, carrying_bag, walking_state], Cyclist: [bicycle_type, helmet_worn] }加载后当用户选择Car类型时标注面板自动追加三个输入框其值将写入 JSON 的attributes字段。此功能无需后端纯前端 Schema 驱动。5.3 导出前校验防止无效标注进入训练集在export.js中插入校验逻辑拦截明显错误function validateAnnotation(obj) { // 检查 2D 框是否超出图像边界 const [x1, y1, x2, y2] obj.bbox_2d; if (x1 0 || y1 0 || x2 imageWidth || y2 imageHeight) { alert(警告${obj.id} 的 2D 框超出图像范围请修正); return false; } // 检查 3D 尺寸是否合理轿车高度不可能为 0.1m const [h, w, l] obj.dimensions; if (obj.type Car (h 1.2 || h 2.5)) { alert(${obj.id} 的高度 ${h}m 不在合理区间1.2–2.5m请确认); return false; } return true; } // 导出前遍历所有 objects if (!annotations.objects.every(validateAnnotation)) { return; // 中断导出 }该校验在点击「导出」按钮时触发覆盖 80% 的人工误标场景避免脏数据污染模型训练。最后提醒3D-BAT 的README.md明确声明「不提供云端存储、用户权限或标注进度同步」。若需团队协作应自行对接 Firebase Realtime DB 或轻量级 Express API将export.json上传至私有服务器——这恰是其定位一个可嵌入、可审计、可离线的标注基座而非 SaaS 化黑盒工具。本文还有配套的精品资源点击获取