# UVE · 三维 GIS 与遥感影像处理开源工具 — 全量文本 三维 GIS、摄影测量与遥感影像处理的开源工具:OBJ 模型转正射影像、正射影像建筑物轮廓提取、建筑物分割模型训练、无人机视频融合投射。全部 MIT 开源。 GitHub: https://github.com/UVE1048 --- # 把 OBJ 模型变成能进 GIS 的正射影像 倾斜摄影生产链里,模型通常停留在三维。制图、变化检测、建筑物提取都需要二维正射影像。这个工具把「三维模型 → 带坐标系的 GeoTIFF」这一步做成了命令行操作。 源码:https://github.com/UVE1048/ObjOrthoRender 在线文档:https://uve1048.github.io/obj-ortho-render/ ## 别名与同义词 OBJ 转 DOM、模型转正射影像、三维模型出正射图、倾斜摄影导出正射、orthophoto generator、mesh to orthophoto、OBJ2DOM、OBJ to GeoTIFF converter ## 你会遇到的问题 - 商业三维软件能导出正射,但要人守着点鼠标,上千个图块没法批处理。 - 换成写脚本吧,OpenGL 一吃显存就崩,单个模型的面数和纹理尺寸都能顶到上限。 - 生产环境是台没有独显的服务器,任何依赖硬件 OpenGL 的方案直接卡死。 ## 它怎么解决 ### 分块渲染 单个超大模型内部再切 tile,逐块渲染并直接写入 GeoTIFF,绕开纹理尺寸与显存上限。 ### 地理参考 读 metadata.xml 的 SRS 与 SRSOrigin,把坐标系和原点写进输出,QGIS 打开即定位。 ### 无显卡可跑 Docker 镜像内置 Xvfb + Mesa 软件 OpenGL,服务器没有 GPU 也能出图,慢但不失败。 ### 三级合并 all / subfolder / none 三种策略,合并优先走 osgeo.gdal,大范围批产可控内存。 ## 快速开始 ```bash pip install objorthorender # 已在 PyPI 发布 objorthorender --input path/to/input \ --output path/to/output \ --gsd 0.05 --workers 4 --merge-mode all # 先用自带样例跑通 objorthorender --input examples/sample --output out --gsd 0.5 ``` > 输入的 metadata.xml 必须与出模时的坐标系一致。SRSOrigin 是模型局部原点对应的真实坐标,写错会导致整体偏移 —— 这是最常见的问题。 ## 参数 | 参数 | 默认 | 说明 | | :--- | :--- | :--- | | `--input` | 必填 | 输入目录,递归查找 .obj | | `--output` | <input>/MergedDOM | 输出目录 | | `--metadata` | <input>/metadata.xml | 可指定任意路径 | | `--gsd` | 0.05 | 地面采样距离,米/像素 | | `--workers` | CPU 核数 | 并行进程数 | | `--merge-mode` | all | all / subfolder / none | | `--fill-holes` | on | off / on / fast / strong | ## 常见问题 ### 怎么把 OBJ 三维模型转成带地理坐标的正射影像? 用 render_orthophotos.py,指定 --input 指向 OBJ 所在目录、--output 输出目录、--metadata 指向 metadata.xml。程序会递归查找 .obj,逐块渲染并写入带 SRS 与 SRSOrigin 的 GeoTIFF。 ### 倾斜摄影模型怎么导出 DOM(数字正射影像图)? 先把 3D Tiles 转成 OBJ,再用本项目渲染成 GeoTIFF。倾斜摄影模型内部再切 tile 渲染,所以单个模型面数极大时也不会撞上显存或纹理尺寸上限。 ### 没有独立显卡的服务器能跑吗? 能。Docker 镜像内置 Xvfb 与 Mesa 软件 OpenGL,纯 CPU 渲染,速度慢于 GPU 但不会失败。本机运行时需要可用的 OpenGL 3.3+。 ### 输出的正射影像在地图上整体偏移怎么办? 检查 metadata.xml 里的 SRSOrigin。它是模型局部坐标原点对应的真实地理坐标,必须与出模时一致。另外确认 SRS 写的是 EPSG:3857 而不是 EPSG:4326。 ### 支持哪些坐标系? 任意 EPSG 代码,读取 metadata.xml 的 SRS 字段并写入输出 GeoTIFF,QGIS 与 ArcGIS 打开即定位。 --- # 从正射影像提取能直接入库的建筑图斑 给一张带地理参考的正射影像,输出建筑物轮廓 Shapefile。和「跑个分割模型就完事」的区别在于后处理:从像素掩码到可入库的图斑,中间还有校验和规则化两步。 源码:https://github.com/UVE1048/Footprint-Creater 在线文档:https://uve1048.github.io/footprint-creater/ ## 别名与同义词 建筑物提取工具、房屋面提取、建筑轮廓矢量化、建筑物普查、building polygon extraction、footprint extraction tool、建筑图斑提取 ## 你会遇到的问题 - 现成的分割模型直接转矢量,得到的是一堆锯齿边、粘连块和碎屑,导入 GIS 之后还得人工重画。 - 大影像装不进显存,分块推理拼回来又会在接缝处产生假轮廓。 - 正射影像四周是黑的,模型会稳定地把黑边识别成大片区建筑,面积过滤还拦不住。 ## 它怎么解决 ### 掩码前置 推理前就用 Nodata、纯黑、植被、阴影掩码把干扰区涂黑,推理后再强制剔除。这是针对黑边误检的关键。 ### 全局校验 各块推理完先 OR 合并成全局掩码,再做轮廓校验(面积、宽度、矩形度、实心度、植被冲突、阴影支撑),而不是逐块美化后拼接。 ### 保直角平滑 用 join_style=mitre 先膨胀后腐蚀,保持直线和直角,不做圆角化 —— 建筑的边是直的。 ### 简化与矩形化 Douglas-Peucker 简化后,若与最小外接矩形 IoU 超过阈值则替换为规则矩形。 ## 快速开始 ```bash git clone https://github.com/UVE1048/Footprint-Creater.git cd Footprint-Creater pip install -r requirements.txt python scripts/download_models.py # 预训练权重,约 773 MB python web_app.py # 打开 http://localhost:5000 ``` > 影像必须是带地理参考的正射影像。没有像素大小和坐标系,面积过滤会失效,SHP 也无法定位 —— 这是新手最常踩的坑。 ## 参数 | 参数 | 默认 | 说明 | | :--- | :--- | :--- | | `BLOCK_SIZE` | 1024 | 分块推理像素尺寸,显存不足调小 | | `BLOCK_OVERLAP` | 512 | 分块重叠,建议保持 50% | | `MIN_AREA_M2` | 100.0 | 最小建筑面积,过滤噪点 | | `BUFFER_EXPAND_M` | 0.6 | 平滑膨胀距离,米 | | `BUFFER_SHRINK_M` | 0.3 | 平滑腐蚀距离,米 | | `SIMPLIFY_TOL` | 0.3 | Douglas-Peucker 公差,米 | | `RECT_IOU_THRESH` | 0.90 | 矩形化 IoU 阈值 | ## 常见问题 ### 怎么从正射影像自动提取建筑物轮廓? 启动 web_app.py 打开控制台,上传带地理参考的 .tif,点开始处理。程序会执行分块推理、全局轮廓校验、简化与矩形化,最后输出 buildings.shp 及预览图。 ### 提取出来的轮廓边缘很锯齿、还有粘连怎么办? 这是直接拿语义分割掩码转矢量的典型结果。本项目在转矢量前做了全局轮廓校验(面积、宽度、矩形度、实心度、植被冲突、阴影支撑),之后再用 mitre 保直角平滑,最后做 Douglas-Peucker 简化,IoU 超过阈值的图斑替换为规则矩形。 ### 为什么影像黑边会被识别成大片建筑物? 斜切的正射影像四周是黑色 Nodata,分割模型会稳定地把这块区域判成建筑,而且连成一片导致面积过滤拦不住。本项目在推理前就用 Nodata、纯黑、植被、阴影掩码把干扰区涂黑,推理后再强制从结果剔除。 ### 输出的 Shapefile 在 ArcGIS 里没有坐标系? 输出时会尽量把 CRS 转成整数 EPSG 码再写出,保证 .prj 被正确识别;拿不到 EPSG 时退回原始 CRS WKT 并手工补写 .prj 文件。 ### 跑一张影像需要多少显存? 8 GB 显存下 BLOCK_SIZE=1024、BLOCK_OVERLAP=512 是稳妥配置。显存不足就调小 BLOCK_SIZE,大建筑常被切断时调大。 --- # 用你自己的影像训一个建筑分割模型 公开数据集上训好的模型,换到你的城市就未必准。这个仓库把「大影像加矢量标签 → 切片数据集 → 训练 → 大图推理」整条链路补齐了。 源码:https://github.com/UVE1048/HRNet-Footprint-Trainer 在线文档:https://uve1048.github.io/hrnet-footprint-trainer/ ## 别名与同义词 建筑物分割训练、HRNet 训练脚本、遥感分割训练模板、建筑物提取模型训练、building segmentation training、HRNet segmentation pipeline ## 你会遇到的问题 - 公开数据集训练的模型,到高密度城区就粘连:楼挨得太近,几栋连成一片。 - 阴影方向不一样,学到的边界会系统性偏移;屋顶材质差异大,彩钢瓦直接漏检。 - 想自己训,却发现切片、标签栅格化、大图推理拼接每一段都要自己写。 ## 它怎么解决 ### 滑窗切片 以 1024 为窗口、512 为步长对大影像重叠裁切,50% 重叠消除边缘效应。增量式:已存在的切片自动跳过,补数据不用重来。 ### 前景占比过滤 建筑像素占比低于 1% 或高于 98% 的切片丢弃。全空和全满样本没信息量,丢掉显著降低训练时间。 ### NoData 忽略 把纯黑纯白区域在标签里置为 ignore_index,模型不会因为「把黑边预测成背景」被惩罚。这是全套流程里最见效的改动。 ### 重叠滑窗推理 重叠窗口预测后拼接,既绕开显存限制,也用重叠区加权消除拼缝断层。 ## 快速开始 ```bash git clone https://github.com/UVE1048/HRNet-Footprint-Trainer.git cd HRNet-Footprint-Trainer conda create -n footprint python=3.10 -y && conda activate footprint conda install -c conda-forge geopandas rasterio -y pip install -r requirements.txt cp prepare/DATA.example.TXT prepare/DATA.TXT # 填入影像与矢量路径 python prepare/prepare_dataset_multiprocess.py python train.py ``` > 标签质量决定上限。矢量与影像套合不准时,模型学到的是系统性边界偏移,加数据也没用。训之前先抽几处叠加检查。 ## 参数 | 参数 | 默认 | 说明 | | :--- | :--- | :--- | | `CROP_SIZE` | 1024 | 切片边长,像素 | | `STRIDE` | 512 | 滑窗步长,即 50% 重叠 | | `TRAIN_RATIO` | 0.8 | 训练集比例 | | `MIN_FG_RATIO` | 0.01 | 低于此建筑占比的切片丢弃 | | `MAX_FG_RATIO` | 0.98 | 高于此建筑占比的切片丢弃 | | `--crop-size` | 1024 | 推理滑窗边长,与训练一致 | ## 常见问题 ### 怎么用自己的数据训练一个建筑物提取模型? 准备正射影像 .tif 与建筑物轮廓 .shp(坐标系必须一致),填进 prepare/DATA.TXT,运行 prepare_dataset_multiprocess.py 生成切片数据集,再运行 train.py 训练,最后用 predict.py 对大图做滑窗推理。 ### 影像太大装不进显存怎么办? 训练阶段用 1024 滑窗、512 步长切片;推理阶段用重叠滑窗预测再拼接。两处都靠重叠消除边缘效应与拼缝断层。 ### 正射影像的黑边会干扰训练吗? 默认已处理。MaskNoData 变换会把纯黑 (0,0,0) 与纯白 (255,255,255) 区域在标签里置为 ignore_index,算 loss 时完全跳过,模型不会因为「把黑边预测成背景」被惩罚。 ### 训练需要多少标注数据? 这项任务的边界精度高度依赖标注质量而非数量。标签与影像套合不准时,模型学到的是系统性边界偏移,加数据也无法纠正。训之前务必抽几处叠加检查。 ### mmcv 装不上 / 编译失败怎么办? 换 pip install mmcv-lite>=2.1.0。train.py 里已有一行版本号 hack 绕过 MMSegmentation 的强校验,predict.py 里内置 mmcv.ops 的 polyfill,不需要 CUDA 算子也能推理。 --- # 把无人机画面直接投到三维模型上 与其在角落放个小窗让操作员心算对应关系,不如把画面按相机位姿投影到模型表面 —— 画面和地物处在同一空间,遮挡、朝向、覆盖范围全部自洽。 源码:https://github.com/UVE1048/VideoFusion-Web 在线文档:https://uve1048.github.io/video-fusion-web/ ## 别名与同义词 视频融合示例、无人机视频投影、视频贴模型、视频投射 SDK 用法、video projection onto 3D model、UAV video fusion ## 你会遇到的问题 - 画面在小窗里,三维场景在背后,两者之间靠人脑映射。紧急情况下这个映射成本很高。 - 投影位置偏一点,整幅画面就错位。位姿、FOV、画幅、模型坐标系,任一项不对都不行。 - 多路同时投射会互相干扰,WebGL 下多路视频纹理的显存开销也很陡。 ## 它怎么解决 ### 位姿一次算对 位置、姿态、FOV、画幅是一组强耦合参数。校验办法是在场景里放已知坐标的地面标记,让视频里的同一地物正好压上去。 ### 单路激活 同一时刻只开一路投射,其余仅保留位置指示。这是刻意的产品逻辑,不是没做多路。 ### video 元素复用 切换无人机时不重建 video,而是把它重新绑定到另一个投射对象,避免解码器反复初始化的卡顿。 ### 连线跟相机走 小窗到无人机的连线必须在渲染循环里更新,否则相机一动连线就脱节。 ## 快速开始 ```bash # 本仓库为设计文档,不含可运行源码 # 复刻时的目录划分与命令约定: npm install # 前端依赖 cd stream_server && npm install && npm start # 本地流服务,8088 npm run dev # 前端 ``` > 本仓库只包含设计与实现要点,不含源码。视频融合真正难的不是调 API,而是位姿对齐与多路流状态管理 —— 这两件事的结论比代码更难复现,所以先写清楚。 ## 参数 | 参数 | 默认 | 说明 | | :--- | :--- | :--- | | `ESVideoFusion` | — | EarthSDK3 的视频投射对象 | | `drones.js` | — | 位置/姿态/FOV/画幅/视频地址 | | `:8088` | — | 本地 HLS 服务端口 | ## 常见问题 ### 怎么把无人机视频投射到三维模型表面? 用 EarthSDK3 的 ESVideoFusion 对象,绑定一个