Metashape Python API 1.82 实战指南:自动化三维重建与批处理

发布时间:2026/11/6 11:39:45
Metashape Python API 1.82 实战指南:自动化三维重建与批处理

简介:面向 Metashape Professional 用户的 Python 脚本开发参考文档,适合已具备一定摄影测量基础、希望用代码替代重复手工操作的中高级用户。内容围绕 Metashape 模块展开,涵盖 Document 类与项目读写、块与相机标记管理、相机校准与地面控制数据配置、照片对齐与密集云建模纹理化等处理流程、模型与 DEM 导出,以及网络任务控制,并附有完整示例代码与模块索引,便于按类查函数、快速搭建自动化处理管线。资源包共 1 个 pdf 文件,约 1.16MB,为官方 Release 1.8.2 英文参考手册,结构按概述、应用模块、变更日志与模块索引组织,适合作为案头查阅资料。目前已有 311 人学习下载,可帮助读者理解 API 调用方式与版本差异,减少脚本调试中的试错成本。

1. 拿到 Metashape Python API 1.82 参考手册,先搞清楚它能替你干什么

如果你手上有一批航拍照片,每次都要在图形界面里点一遍“对齐照片 → 建稠密云 → 建模型 → 贴纹理 → 导出”,那你迟早会想要一个脚本。Metashape Python API 1.82 这份参考手册,解决的就是这件事:它把 Metashape Professional 里几乎所有的处理步骤、项目对象、相机参数、导出接口都暴露成了 Python 调用。手册对应的是 2022 年 3 月发布的 1.8.2 版本,脚本引擎是 Python 3.8,而且只在 Professional 版里可用——Standard 版打开控制台是空的,这一点很多人第一次就翻车。它适合两类人:一类是想把重复的建模流程批量化、自动化的测绘与三维重建从业者;另一类是需要在自有系统里调用重建能力、做二次开发的工程师。手册本身不是教程,是一份类与方法的字典,所以读它的方式决定了你能不能真的用起来。

2. 三种执行入口与 Document 对象模型:脚本到底跑在哪

2.1 控制台、Run Script 与命令行 -r 的取舍

手册开篇列了三种执行方式,但没说清楚各自适合什么场景,这里按我的使用习惯补上。第一种是 Metashape 界面下方的 Console 面板,它就是一个标准 Python 控制台,适合验证单行调用、查对象属性,比如临时敲Metashape.app.document.chunk.cameras看相机列表。第二种是 Tools 菜单里的 Run script...,适合调试阶段反复跑同一个脚本文件,改完保存再点一次即可。第三种是命令行-r参数,这是真正做批量任务时用的,因为它可以脱离人工点击、配合任务计划或批处理脚本运行。

# Windows 下用命令行执行脚本,注意路径带空格要加引号 "C:\Program Files\Agisoft\Metashape Pro\metashape.exe" -r "D:\scripts\batch_build.py" # Linux 下同理,-r 后面跟脚本绝对路径 metashape -r /home/user/scripts/batch_build.py

这里的逻辑是:-r让 Metashape 启动后直接执行指定脚本,脚本跑完进程按脚本逻辑退出。参数上唯一要盯的是路径——Windows 下 Program Files 带空格,整条可执行文件路径必须用引号包住,否则命令行会把C:\Program当成程序名,报“找不到文件”。另外命令行模式下没有界面交互,脚本里任何Metashape.app.getOpenFileName()这类弹窗调用都会卡住或直接失败,批量脚本里要全部换成硬编码路径或从配置文件读。

2.2 Document、Chunk、Camera 的层级关系

手册第 2 章的核心是Document类,它代表一个.psz项目文件。一个 Document 下可以挂多个 Chunk,Chunk 才是真正装照片、点云、模型、纹理的容器。理解这个层级,后面所有调用才不会写错对象。当前界面里打开的项目通过Metashape.app.document拿到,不需要自己 new。下面这段是手册示例的整理版,也是我建议新手第一个跑通的完整流程:

import Metashape # 拿到当前打开的项目文档对象 doc = Metashape.app.document doc.open("project.psz") # 打开已有项目,路径按实际改 chunk = doc.chunk # 取当前激活的 chunk # 照片对齐:downscale=1 表示用原图分辨率做特征匹配 chunk.matchPhotos(downscale=1, generic_preselection=True, # 通用预筛选,先粗筛配对 reference_preselection=False) chunk.alignCameras() # 深度图与稠密云:downscale=4 是速度与质量的折中 chunk.buildDepthMaps(downscale=4, filter_mode=Metashape.AggressiveFiltering) chunk.buildDenseCloud() # 建模与纹理 chunk.buildModel(surface_type=Metashape.Arbitrary, interpolation=Metashape.EnabledInterpolation) chunk.buildUV(mapping_mode=Metashape.GenericMapping) chunk.buildTexture(blending_mode=Metashape.MosaicBlending, texture_size=4096) doc.save()

逐段说参数。matchPhotos的downscale决定特征提取的图像缩放级别,1 是原图、2 是半分辨率,数值越大越快但弱纹理区域越容易匹配失败;generic_preselection打开后先按图像内容粗筛可能重叠的照片对,照片多的时候能省大量时间,reference_preselection则依赖相机 GPS 位置来筛,没有 POS 数据时开了也没用。buildDepthMaps的downscale=4是常见起点,追求细节可以降到 2,代价是显存和时间成倍上涨;AggressiveFiltering对噪声和飞点抑制更狠,适合植被、水面这类难处理的场景,但会削掉一些细薄结构。buildModel里Arbitrary是任意拓扑,适合雕塑、建筑这类非地形对象,地形类项目通常换HeightField。buildTexture的texture_size=4096是纹理图幅,4096 对大多数展示够用,要印刷级再往上加,但显存和导出体积也跟着涨。

提示:doc.chunk取的是当前激活 chunk,多 chunk 项目里如果激活的不是你要处理的那个,脚本会默默处理错对象。稳妥写法是chunk = doc.chunks[0]或按 label 查找。

2.3 Application 对象:弹窗、坐标系与 GPU 掩码

Metashape.app是全局应用对象,手册里它承担两类职责:一类是交互式弹窗(选文件、选坐标系、输入数值),另一类是全局配置(GPU 设备、CPU 开关、版本号)。交互式弹窗在手动跑脚本时很方便,比如让用户选坐标系再套到 chunk 上:

import Metashape doc = Metashape.app.document # 弹出坐标系选择框,默认值用当前 chunk 的 crs crs = Metashape.app.getCoordinateSystem("选择坐标系", doc.chunk.crs) doc.chunk.crs = crs path = Metashape.app.getSaveFileName("项目另存为") try: doc.save(path) except RuntimeError: Metashape.app.messageBox("保存失败,检查路径权限")

getCoordinateSystem返回一个CoordinateSystem对象,取消对话框时返回None,所以生产脚本里必须判空,否则把None赋给chunk.crs会抛异常。save包在 try 里是因为磁盘满、路径无权限、文件被占用都会抛RuntimeError,手册示例也是这么处理的。GPU 这块,Metashape.app.gpu_mask是位掩码,值 5 表示二进制 101,即启用 0 号和 2 号设备、跳过 1 号,多卡机器上想留一张卡给别的任务就靠它;cpu_enable控制 GPU 工作时是否仍用 CPU 参与,纯 GPU 跑深度图时关掉能减少资源争抢,但某些步骤没有 CPU 回退会直接失败,建议先保持默认。

3. 相机标定与 Calibration 类:内参读写和投影误差怎么算

3.1 Calibration 的字段含义与 load/save

Calibration类装的是相机内参:焦距f、像主点cx/cy、径向畸变k1到k4、偏心畸变p1到p4、仿射与非正交项b1/b2,还有图像宽高。手册给了load(path, format)和save(path, format, ...),默认格式是 XML。实际项目里经常遇到外部标定文件(比如某些相机厂商导出的参数),需要灌进 Metashape 再参与空三,这时就用load:

import Metashape chunk = Metashape.app.document.chunk cam = chunk.cameras[0] # 从 XML 标定文件加载内参到该相机 calib = Metashape.Calibration() calib.load("calib_camera.xml", Metashape.CalibrationFormatXML) cam.sensor.calibration = calib # 反过来,把当前标定导出备份 cam.sensor.calibration.save("calib_backup.xml", Metashape.CalibrationFormatXML)

逻辑上,标定挂在sensor上而不是单张camera上,因为同一台相机拍的一组照片共享一套内参。load的第二个参数是格式枚举,手册里默认CalibrationFormatXML,如果你的文件是其他格式要换成对应枚举值,格式不匹配会直接抛错。save还支持额外传label、pixel_size、focal_length等参数,导出给外部工具时按对方要求填。

3.2 project 与 error:用投影误差判断标定质量

Calibration.project(point)把三维点投影到像素坐标,error(point, proj)算投影点与实测像素点的二维误差。这两个方法在自检标定质量时很有用——把控制点或连接点投回去,看残差分布。常见做法是遍历 chunk 里的 tie points,统计误差均值,超过阈值就说明标定或对齐有问题:

import Metashape chunk = Metashape.app.document.chunk cam = chunk.cameras[0] calib = cam.sensor.calibration errors = [] for point in chunk.tie_points.points: # 取该点在当前相机上的投影 proj = point.projections.get(cam) if proj is None: continue # 三维坐标投到像素平面,再和实测投影比 err = calib.error(point.coord, proj.coord) errors.append(err.norm()) if errors: avg = sum(errors) / len(errors) print("平均投影误差(像素):", avg)

point.coord是三维坐标,proj.coord是该点在图像上的像素坐标,error返回一个二维向量,取norm()得到标量误差。像素误差在 0.5 像素以内通常算健康,超过 1 像素要回头查标定文件是否对、镜头是否有变化、对齐时是否混入了不同相机。这段代码跑在稠密云之前,能提前发现问题,比建完模型才发现纹理错位省事得多。

4. 批处理与导出:把重复劳动压成一条命令

4.1 多 chunk 循环与结果导出

真正体现脚本价值的是批量。一个项目里多个 chunk 对应不同区域或不同架次,逐个跑流程再导出,比手点快一个数量级。下面这段把每个 chunk 走一遍建模并导出 OBJ 和正射影像:

import Metashape, os doc = Metashape.app.document out_dir = "D:/output" os.makedirs(out_dir, exist_ok=True) for chunk in doc.chunks: print("处理 chunk:", chunk.label) chunk.matchPhotos(downscale=2, generic_preselection=True) chunk.alignCameras() chunk.buildDepthMaps(downscale=4, filter_mode=Metashape.MildFiltering) chunk.buildModel(surface_type=Metashape.HeightField, interpolation=Metashape.EnabledInterpolation) # 导出模型,project_path 用 chunk 的 label 区分 model_path = os.path.join(out_dir, f"{chunk.label}.obj") chunk.exportModel(model_path, format=Metashape.ModelFormatOBJ, texture_format=Metashape.ImageFormatJPEG) # 导出正射影像,需要先有 DEM 或模型 ortho_path = os.path.join(out_dir, f"{chunk.label}_ortho.tif") chunk.exportOrthomosaic(ortho_path, format=Metashape.RasterFormatTiles, image_format=Metashape.ImageFormatTIFF)

exportModel的format决定输出格式,OBJ 通用性好但文件大,texture_format控制纹理图格式,JPEG 体积小、TIFF 无损但大。exportOrthomosaic的RasterFormatTiles是分块 GeoTIFF,适合大范围正射,GIS 软件打开更稳;如果只是小范围预览,换成普通 TIFF 即可。注意导出正射前 chunk 里必须有 DEM 或已建模型,否则会报“没有可用表面”,这是新手最常见的顺序错误。

4.2 用 Settings 固化参数,避免每次改脚本

Metashape.Settings提供setValue/value读写应用级配置,save/load落盘。把常用参数(比如默认 downscale、日志路径、是否压缩项目)存进 settings,脚本里读出来用,换机器时只改配置不改代码:

import Metashape settings = Metashape.app.settings # 写入自定义键值,value 可以是任意 Python 对象 settings.setValue("batch/downscale", 2) settings.setValue("batch/log_path", "D:/logs/metashape.log") settings.save() # 持久化到磁盘 # 下次运行或另一台机器读取 ds = settings.value("batch/downscale") print("当前 downscale:", ds)

setValue的 key 用带命名空间前缀的字符串(如batch/xxx)避免和内置键冲突,value支持 int、float、string、bool 等基础类型,复杂对象不建议塞进去。save()不调用的话只在当前会话有效,这点手册没强调,但踩过一次就记住了。

5. 避坑与排查:五个真实会卡住你的点

5.1 脚本在 Standard 版里完全没反应

现象:控制台能打开,敲import Metashape报模块不存在,或 Run script 菜单灰掉。原因:Python 脚本只在 Professional 版启用,Standard 版根本没打包这个模块。解决:确认授权版本,Standard 版只能走图形界面,没有绕过的办法。

5.2 命令行 -r 执行后进程不退出

现象:批处理脚本跑完,Metashape 进程还挂着,后续任务排队卡死。原因:脚本里调用了Metashape.app.quit()之外,界面模式下进程默认常驻;命令行模式若脚本末尾没有显式退出,某些版本会保持。解决:批量脚本末尾加Metashape.app.quit(),并确认没有未关闭的弹窗调用。

5.3 buildDepthMaps 显存溢出

现象:跑到深度图阶段报 GPU 内存不足或直接崩溃。原因:downscale设得太小(如 1)加上高分辨率照片,单张深度图显存需求暴涨。解决:先把downscale调到 4 甚至 8 验证流程通不通,再逐步降;多卡机器用gpu_mask只留一张卡跑,避免多卡同时吃显存。

5.4 坐标系赋值后导出坐标全错

现象:模型导出后坐标偏移几百米或直接是局部坐标。原因:chunk.crs设了但照片的 GPS/控制点没同步,或getCoordinateSystem返回None被直接赋值。解决:赋值前判空,赋值后检查chunk.crs是否真的变了,控制点坐标要按目标坐标系重新导入。

5.5 纹理导出后模型是纯色

现象:OBJ 打开没有贴图,或贴图全黑。原因:buildTexture之前没跑buildUV,或texture_size超出显存导致纹理生成失败但没抛错。解决:确保buildUV在buildTexture之前,纹理尺寸从 2048 起试,导出时确认texture_format和模型格式匹配。

6. 把手册当字典用:我的检索式读法与一个自检习惯

这份 1.82 手册两百多页,从头读到尾不现实,我的用法是把它当字典:先想清楚要操作哪个对象(Document、Chunk、Camera、Calibration、Settings),再翻到对应类,只看方法签名和参数类型,示例代码扫一眼就够。真正要花时间的是记住对象层级——app.document→chunks→chunk.cameras/sensors/tie_points,层级对了,方法名靠 IDE 补全就能找到。另一个习惯是每个脚本跑完先做一次轻量自检,不急着导出大文件:

自检项检查方法健康阈值
对齐相机数len([c for c in chunk.cameras if c.transform])接近总照片数
平均重投影误差遍历 tie points 算calib.error小于 1 像素
稠密云点数len(chunk.dense_cloud.points)与场景规模匹配
模型面数len(chunk.model.faces)按用途控制,展示级百万级以内

这张表是我每次批量任务前必跑的,比等模型建完再发现问题省太多时间。手册里Application.update()也值得记住,长任务里定期调用能让界面不假死,虽然命令行模式用不上,但调试阶段很有用。从那以后我每次写新脚本,都强制先在一个 chunk 上跑通全流程再套循环,绝不直接对整项目开跑——这个习惯帮我躲过了至少两次“跑了一夜发现参数写错”的血泪教训。希望帮到你。

本文还有配套的精品资源,点击获取