# OpenScaner **Repository Path**: haobot/OpenScaner ## Basic Information - **Project Name**: OpenScaner - **Description**: Open Scaner for 3D modeling. - **Primary Language**: JavaScript - **License**: Apache-2.0 - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-21 - **Last Updated**: 2026-07-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # GSModeling — 视频 + 标尺 → 高斯泼溅 → 参数化模型(MVP) 环绕物体拍一段视频(场景内放一个已知边长的 ArUco marker),流水线重建出 真实米制尺度的网格,再反求参数化模板参数,输出**可调参数的 CAD 模型** (CadQuery 脚本 + STEP)。改参数 → 重跑脚本 → 新模型。 方案设计文档:`docs/2026-07-19-gs-video-parametric-modeling-design.md`(链 B,全 Apache-2.0/BSD/MIT 许可)。 ## 流水线六环节 ``` 视频 → [1] 抽帧+COLMAP 位姿 → [2] ArUco 尺度恢复 → [3] GS 训练 → [4] TSDF 网格提取 → [5] 模板拟合 → [6] 参数化输出(model.py / params.json / model.step) ``` | # | 环节 | 实现 | 验证状态 | |---|------|------|----------| | 1 | 抽帧 / COLMAP 重建 | `stages/frames.py`(ffmpeg 封装;pycolmap 引擎为默认,colmap CLI 可选) | ✅ 合成场景实机验证(180/180 帧注册);ffmpeg 抽帧实机验证 | | 2 | ArUco 尺度恢复 | `stages/scale.py`(cv2.aruco 检测 + 多视角三角化) | ✅ 合成场景端到端验证:尺度误差 ~1.2%,相机位置残差 RMS 1.7mm(37 视角) | | 3 | GS 训练 | `stages/train.py`(gsplat 2DGS 为默认,内置 `--no-normalize_world_space --dist_loss --normal_loss`;nerfstudio 备选) | ✅ 合成场景实机训练(PSNR 26–30) | | 4 | TSDF 网格提取 | `stages/tsdf.py`(自建:gsplat 深度渲染 → TSDF → marching cubes;gsplat 后端免 nerfstudio) | ✅ 管线跑通;几何精度受雾状高斯影响(D≈14%),改进方向见 CHANGELOG | | 5 | 模板拟合 | `fit/`(PCA 初值 + least_squares + 贴地约束) | ✅ 合成数据:D/H ≤3%;稀疏点云端到端:D 1.3%、H 8.6%(`scripts/verify_stage0_fit.py`) | | 6 | 参数化输出 | `export.py`(CadQuery 脚本 + params.json + STEP) | ✅ 集成测试验证(STEP 生成、脚本几何与模板一致) | ### 阶段 0 合成验证(可复现) ```bash # 生成 180 帧合成环绕序列(含真值 truth.json) gsmodeling synth-scene --out work/synth --n-frames 180 # pycolmap 稀疏重建(约 2–3 分钟) gsmodeling reconstruct --images work/synth --workspace work/synth_ws # ArUco 尺度恢复 gsmodeling calibrate-scale --images work/synth --workspace work/synth_ws --marker-size 0.10 # 与真值对比(三项指标容差 3%) python scripts/verify_stage0.py work/synth_ws work/synth/truth.json ``` ### GPU 环境(环节 3–4) 本机已有 RTX 4060 8GB(驱动支持 CUDA ≤13.3),已验证可用配置: - **torch 2.12.0+cu126 + torchvision 0.27.0+cu126**:从国内镜像下载 wheel 本地安装 (`https://mirrors.aliyun.com/pytorch-wheels/cu126/`)。注意:pip 装 torchvision 会把 CUDA 版 torch 覆盖为 CPU 版,必须 `--no-deps` 并重装 torch wheel。 - **CUDA Toolkit 12.6**(nvcc,JIT 编译用)+ VS2022 BuildTools(MSVC)。 - **gsplat 1.5.3**(pip)+ 仓库克隆(`tools/gsplat`,checkout v1.5.3 tag 使 examples 与库一致)。 GPU 相关命令统一经 `work/run_with_cuda_env.bat` 运行(封装 vcvars + CUDA_HOME + `DISTUTILS_USE_SDK=1`)。 - 训练入口:`tools/gsplat/examples/simple_trainer_2dgs.py`, **必须带 `--no-normalize_world_space`**(gsplat 默认把场景归一化到单位尺度, 会摧毁环节 2 恢复的米制尺度;`train.py` 的 gsplat 命令已内置该 flag)。 - 已知上游问题及本机补丁见 CHANGELOG「环境适配补丁」。 ### 位姿来源扩展(可选) 流水线环节 1–2(SfM + 标尺)是默认手持采集路径。若有精确运动平台 (如 3D 打印机龙门架/转台),可直接以 G-code 位姿替代环节 1–2, 并跳过尺度恢复,见 `docs/idea/2026-07-21-打印机龙门架精确位姿扫描.md`。 ## 环境搭建 ```bash python -m venv .venv .venv/Scripts/pip install -e .[dev] # Windows;Linux 用 .venv/bin/pip ``` 外部工具(按需): - **ffmpeg**:`winget install ffmpeg`(本机已装,抽帧已验证) - ~~COLMAP~~ 稀疏重建不需要独立安装:环节 1 默认使用 pip 依赖中的 **pycolmap**; **但 MVS 稠密重建(`dense-mvs`)需要 CUDA 版 COLMAP CLI**(pycolmap wheel 无 CUDA)——把官方 colmap-x64-windows-cuda.zip 解压到 `tools/` 下即可被自动发现 - **nerfstudio / gsplat**(环节 3–4,GPU 必需):见下文「GPU 环境」 ## 拍摄采集规范 - 物体静止,相机环绕拍 60–90 秒,保证物体各面入镜;光照均匀,避免透明/强反光物体。 - **ArUco marker**:`DICT_4X4_50`、id=0,打印外边长 ≥10cm,平放在物体旁,全程尽量多帧入镜(尺度恢复的精度取决于 marker 在画面中的像素尺寸)。 - 若需要拟合壁厚等内部结构,拍摄时需覆盖开口/内壁视角;否则壁厚取模板默认值并在 report.json 中标注为 frozen。 ## 使用方法 分步执行(每步均可 `--dry-run` 查看将执行的命令): ```bash # [1] 抽帧(环绕视频 fps=3 约 180–270 帧) gsmodeling extract-frames --video scan.mp4 --images work/images --fps 3 # [2] COLMAP 稀疏重建(用时序匹配器)+ 导出 TXT 模型 gsmodeling reconstruct --images work/images --workspace work # [3] ArUco 尺度恢复,输出米制模型到 work/sparse_txt_scaled gsmodeling calibrate-scale --images work/images --workspace work --marker-size 0.10 # [3'] 无 marker 路径(转台采集 + 游标卡尺):跳过 calibrate-scale, # 直接在任意单位下拟合,再用卡尺实测的一条边锚定到米制 # (锚参数须参与拟合,推荐长边/D,勿用受底面遮挡的 H) gsmodeling fit --source sparse --workspace work --template box \ --out work/parametric --anchor L=0.037 # report.json 会多出 scale_anchor 字段(锚参数/实测值/原始拟合值/缩放比); # 采集规范见 docs/guide/2026-07-21-实拍验证操作指南.md 第 3 节 # [3b] MVS 稠密重建(环节 3 的替代路径,分钟级,需 tools/ 下 CUDA 版 colmap) gsmodeling dense-mvs --workspace work # → work/mvs/fused.ply,然后直接拟合: gsmodeling fit --source mvs --workspace work --template cylinder_container --out work/parametric # [4] GS 训练(需 GPU;gsplat 2DGS,保持 COLMAP 米制坐标系) gsmodeling train --data work --out work/train_out --backend gsplat # [5] TSDF 网格提取(gsplat 后端用本仓库 tsdf 模块,--engine 2dgs) gsmodeling extract-mesh --train-output work/train_out --out work/mesh_out --backend gsplat # [6] 模板拟合 + 参数化输出(真实场景网格务必 --isolate 去地面/聚类/贴地约束) gsmodeling fit --mesh work/mesh_out/tsdf_mesh.ply --template cylinder_container --out work/parametric --isolate # 内壁扫到时可把壁厚也纳入拟合:--free-params D,H,t ``` 全流程串联:`gsmodeling run --video scan.mp4 --workspace work --template cylinder_container` 输出物(`work/parametric/`): - `model.py` — **自包含参数化脚本**,顶部即 D/H/t(或 L/W/H)参数,改值后 `python model.py` 重新生成 STEP - `params.json` — 求解出的参数(单位:米) - `model.step` — CAD 交换格式,可导入 SolidWorks/FreeCAD/Fusion 360 - `report.json` — 拟合残差(rms)、收敛状态、冻结参数说明 ## Web 调试台 逐环节运行、看中间产物(稀疏点云/相机轨迹/拟合残差热力图/模板叠加)的本机 调试界面,适合反复调参重跑 fit 的核心调试循环(全程无 GPU 也可玩)。 ```bash .venv/Scripts/pip install -e .[web] # fastapi/uvicorn/python-multipart/httpx gsmodeling web # → http://localhost:8000 ``` 后端托管 `web/dist`(前端已构建时直接可用);前端开发走 Vite: ```bash cd web npm install npm run dev # :5173,/api 与 /files 代理到 localhost:8000 npm run build # 产物 web/dist,由后端托管 ``` 工作区即 `work/` 下的子目录(如验证资产 `work/synth_ws`),页面左侧逐环节 点"运行",右侧 3D 视图叠加点云/相机/拟合模板。fit 环节的**数据源开关**对应 两条路径: - **sparse(SfM 稀疏路径,推荐)**:直接拟合尺度已恢复的稀疏点云,跳过 GS 训练/TSDF(环节 3–4),秒级出结果,精度最好(D 误差 ~1.3%); - **dense(GS 密集路径)**:拟合 TSDF 网格采样点,需先跑 train + extract-mesh (GPU),当前几何精度未达标(D≈14%),仅用于调试密集管线。 ## 测试 ```bash .venv/Scripts/python -m pytest -q ``` 覆盖:SDF 单测、圆柱/方箱合成数据拟合精度(≤3%)、多随机位姿稳定性、 尺度恢复几何(三角化/任意尺度)、COLMAP TXT 解析与缩放、ffmpeg 真实抽帧、 端到端集成(网格→拟合→STEP/脚本)。 ## 已知限制(MVP) - 模板库仅 2 种:`cylinder_container`(D、H、t)、`box`(L、W、H);自由曲面件不支持(走 FreeCAD 人工兜底,见设计文档)。 - 壁厚等外表面不可观测参数默认冻结为先验值(`report.json` 的 `frozen_params`)。 - COLMAP 相机模型仅支持针孔类(SIMPLE_PINHOLE/PINHOLE/SIMPLE_RADIAL),SIMPLE_RADIAL 畸变系数在三角化时被忽略——marker 远离画面边缘时影响可忽略。 - 环节 3–4 的命令封装按 nerfstudio/gsplat 文档编写,未在本机实机跑通(GPU 环境未配),首次实机运行时可能需要按实际版本微调参数。