图像拆分理解技能介绍
前几天看到mineru官方的比赛,有一个工程图纸解析的项目拿了一等奖。我参照agent-browser,设计了一个类似的图纸解析技能,希望能帮助到大家,技能地址在SkillHub-图纸拆分理解
很多图纸一张A3纸都装不下,在电脑上也需要缩放才能看清细节;各种图例、术语也很复杂,非专业人员无法理解;很多图例、标尺都隐藏在图纸的角落里,需要不断反复查才能顺利理解,所以图纸解读还是有一定的难度的。出于保密要求,我找了一个示意图,实际图像更复杂一些:

我的同事反应,目前市面上的各种大模型,在图纸理解上有很大的问题,图像尺寸、压缩信息损失都会让视觉大模型得出错误的结论。参照agent-browser技能的核心思路,我设计了一个图像拆分理解的技能,大致思路如下:
python
参照 agent-browser"先结构化、再按编号查询"的思路,该技能将大尺寸图纸切分为带重叠区域的子图,逐块识别文字、符号、图例和空间关系,再根据坐标偏移把结果复原为带全局编号和位置信息的结构树。后续回答直接查询结构树和区域索引,并通过冲突标记、模糊标记、坐标验证及标尺标定控制误识别和幻觉,从而减少图像压缩与细节遗漏造成的错误。
整体效果方面,在glm-53-flash的帮助下,我找了一张施工图给我的两位男同事看,他们都答错了,我也答错了,技能回答对了 (因为真正的答案不在我的问题区域,而是在图中另一个角落的文字里);我还找过一张"水塔线路图",有一些专业术语与行业特殊数据,在技能的帮助下,我成功的理解了这些有一定专业壁垒的数据。
1. 技能定位:为什么复杂图纸不能直接"整图识别"
"图像拆分理解"是一套面向大尺寸、高密度图像的结构化识别技能,主要用于施工图、地形图、CAD 导出图、扫描图纸、复杂报表和超长截图。
这里的"复杂"不只是图像尺寸大,更重要的是信息密度高、元素关系密集。一张施工图可能同时包含道路中心线、建筑红线、管线走向、桩号、设备编号、坐标、高程、比例尺、指北针、图签和设计说明;一张地形图还可能叠加等高线、水系、道路等级、地物符号和坐标网格。这些元素相互交叉,而且很多关键内容只占据很小区域。
如果直接把整张图输入视觉模型,模型看到的通常不是原始分辨率图像,而是一张被压缩后的整图。压缩后,大型轮廓仍然存在,但小字号文字、细线型差异、图例符号和边缘说明会首先丢失。对普通照片来说,丢失部分细节未必影响主题判断;对施工图来说,一个字符、一个符号或一条线型的误读,就可能直接改变结论。
例如:
480 m被误读成084,距离信息会完全失效;YJLW03被误读成YJLWOS,材料型号会发生实质变化;- 粗实线与粗虚线在整图压缩后变得接近,可能导致现状管线与规划管线混淆;
- 某段道路没有直接在道路旁标注名称,但名称写在图纸下方的附属说明中,整图粗看容易漏掉;
- 图例位于右下角,而符号分布在图纸各处,只识别局部时无法知道符号含义。
图像拆分理解要解决的就是这类问题。它不是简单地"把大图切成小图",而是把整图拆成足够清晰的局部,逐块精读,再通过坐标系统把分散的识别结果复原到同一空间中,最后形成可以检索、比较和复核的结构化结果。
因此,它能够完成的不只是文字识别,还包括:
- 图例识别:建立"符号---含义"的映射,再解释图中的专业符号;
- 位置关系判断:用全局坐标验证元素是否相邻、相交、位于某一方位;
- 距离和尺寸计算:通过比例尺或已知长度完成像素与实际距离的换算;
- 跨区域综合分析:比较不同区域中的线型、文字、符号和空间关系;
- 附属信息检索:同时检查图面、图签、说明文字、表格和图例;
- 局部复核:对模糊文字、冲突结果、数字和型号进行高清重读。
在特定任务上,这种流程可以优于一次性人工浏览。人眼面对密集图纸时,容易受到注意力和视觉工作记忆限制。例如,图面上某个路段没有直接写路名,人工查看时可能据此判断"图中没有标注路名";但如果图纸下方的附属说明写着"本段道路为滨江大道改建段",那么更准确的说法应该是:
道路旁未直接标注路名,但说明文字中给出了路段名称。
这两句话的证据强度不同。前者表示没有空间标注,后者表示图纸仍以文字形式提供了名称。图像拆分理解会把图面标注和附属说明都纳入结构树,因此不容易漏掉这类细节。
我认为,这项技能的核心价值不是"看得更细",而是把图像从一张只能整体观看的图片,转化为一份可以定位证据、追踪来源、反复查询的结构化材料。真正可靠的图纸理解,必须同时回答"内容是什么""它在哪里""依据来自哪里""这是原文还是推断"。
2. 核心思想:把图像转换成结构树
2.1 什么是结构树
结构树是一种按元素组织图像内容的数据结构。每个元素都有编号、类型、内容和全局坐标。下面是一份真实任务生成的结构树节选,原图为一张约 6740 × 4768 像素的水塔断面图,图中包含高程标尺、水塔、供水管道、线路跨越和标尺等内容
json
{
"image": "某水塔断面图.png",
"size": [6740, 4768],
"nodes": [
{
"id": "E001",
"type": "axis",
"content": "左侧高程标尺 890---1010 m,每格 10 m",
"bbox": [360, 150, 400, 4768]
},
{
"id": "E002",
"type": "legend",
"content": "整图未发现独立图例区,四角及图签处均无图例表",
"bbox": null
}
]
}
其中:
id是元素编号,用于后续引用;type表示元素类型,如文字、表格、图例、线条或符号;content是识别出的原文或结构化描述;bbox是边界框,即bounding box,表示元素在图像中的矩形范围,格式通常为[左上角x, 左上角y, 右下角x, 右下角y]。
这个例子表示:编号 E017 是一个文字元素,其内容为"滨江大道",位于校正后图像坐标系的 [1144, 340, 1289, 372] 区域。
如果没有结构树,图像只是一组像素。模型也许能"看见"某段文字,却难以在后续问题中稳定地再次找到它,更难说明某个结论来自图中的哪一处。有了结构树后,图像中的文字、表格、符号和说明都变成了可编号的对象。
2.2 结构树为什么重要
第一,结构树让图像内容可以被检索。
例如用户问:
图中有没有给出该路段名称?
如果没有结构树,模型需要重新扫视整图;有了结构树,可以直接检索所有 content 字段,检查道路附近文字、设计说明、图签和表格中是否出现路名。这样既能减少重复读取,也能避免只检查道路附近而漏掉附属说明。
第二,结构树让每个结论都有位置依据。
回答可以写成:
E118(x=4210,y=6025)的说明文字写明:"本段道路为滨江大道改建段。"
这比笼统地说"图中提到了滨江大道"更可靠,因为结论可以追溯到具体元素和具体坐标。
第三,结构树支持跨区域比较。
很多工程问题不是单独识别某个文字,而是比较不同区域之间的关系。例如:
- 两条管线在哪里交叉;
- 哪个接地点距离道路中心线更近;
- 某设备位于红线内还是红线外;
- A 路段和 B 路段是否使用同一种线型;
- 图例中定义的符号在整张图中出现了几次。
这些问题都要求模型同时理解多个区域。只有将不同子图恢复到同一个全局坐标系,才能进行这类比较。
第四,结构树减少重复读取并保证前后一致。
同一张图可能连续有多个问题:
- 图中有哪些管线?
- 电力管线经过哪些道路?
- 两个接头井相距多远?
- 某设备位于哪个路段?
如果每个问题都重新识别整图,不仅成本高,还可能产生不一致:第一次把某编号识别为 J12,第二次识别为 J1Z。结构树落盘后,后续问题默认查询已有结果;只有缓存缺失、模糊或冲突时,才对局部重新识别。
3. 与 agent-browser 的关系
这个技能的设计受到 agent-browser 启发。agent-browser 可以理解为"网页代理浏览器":它浏览网页时,不会每一步都重新观察整个页面,而是先把网页解析为结构树。
网页本身具有 DOM 结构。DOM 即文档对象模型,可以理解为浏览器把网页中的标题、段落、按钮、表格和输入框组织成一棵对象树。agent-browser 会给这些对象分配编号,后续操作直接引用编号,例如"点击 E023"或"读取 E008"。
图像拆分理解把同样的思想迁移到图像中:
| agent-browser | 图像拆分理解 |
|---|---|
| HTML 页面 | 大尺寸图像 |
| DOM 结构树 | 图像结构树 tree.json |
| 页面元素编号 | 图像元素编号,如 E017 |
| 元素位置 | 全局边界框 bbox |
| 元素父子关系 | 表格、单元格、段落、符号之间的层级 |
| 后续操作引用编号 | 后续回答引用编号和坐标 |
| 不反复读取整个页面 | 不反复读取整图 |
区别在于,网页天然具有 DOM,而图像没有。图像中的文字、线条、符号和表格只是像素上的组合,并不会主动告诉模型"我是一个元素"。因此,该技能必须通过切分、逐块识别、坐标复原、重复元素融合和区域索引,人为构造出类似 DOM 的结构。
这就是"图像拆分理解"的本质:先把图像拆小到模型能够看清,再把识别结果恢复到整图空间,最后形成一棵可供后续查询和推理的结构树。
4. 总体流程
完整流程包括一个预检步骤和五个正式步骤:
- 第 0 步:预检方向、分辨率和任务边界;
- 第 1 步:切分图像;
- 第 2 步:识别图例;
- 第 3 步:逐块识别;
- 第 4 步:坐标复原与内容融合;
- 第 5 步:基于结构树回答问题。
这六步不能随意跳过。预检决定图像是否具备可靠识别条件;切分保证局部清晰;图例提供专业符号词典;逐块识别获取局部证据;坐标复原建立全局关系;结构树则支撑最终回答。
5. 第 0 步:预检
预检要回答三个问题:
- 图像方向是否正确;
- 图像分辨率是否足够;
- 问题是否需要额外标定或拆分。
5.1 方向校正
CAD 图纸导出的 PDF、扫描图纸经常带有 90°、180° 或 270° 旋转。文字倒置或竖排时,模型很容易产生稳定但错误的识别结果。例如,把 480 m 看成 084,或者把字母 O 和数字 0 混淆。
流程会先生成一张缩略图,检查文字阅读方向。方向异常时,先旋转再切分,例如:
bash
python split_image.py 施工图.png --rotate 90
旋转后,所有坐标都使用"校正帧坐标"。所谓校正帧,就是方向校正后的图像坐标系。这样可以避免一部分结果使用原图坐标、另一部分结果使用旋转后坐标。
校正后还要抽取一张含文字的子图验证方向。这个成本很低,却能避免整批子图在错误方向上被识别。
5.2 分辨率和文字高度检查
如果原图分辨率不足,强行识别不会产生可靠结果,只会产生看似合理的错误。
判断标准是:子图中的正文文字高度原则上不低于 12 px。若达不到,应依次尝试:
- 对 PDF 或矢量图提高渲染 DPI;
- 减小切分块,让局部获得更高的有效分辨率;
- 对关键区域单独高清裁剪;
- 对仍无法确认的内容标记为
illegible或uncertain。
illegible 表示无法辨认,uncertain 表示识别结果不确定。它们不是失败标记,而是防止幻觉的诚实标记。
例如,一个设备编号只能确认前两位是 YJ,后几位模糊,那么应写成:
json
{
"content": "YJ□□□",
"status": "illegible"
}
而不是根据常见型号补成 YJLW03。
5.3 多图任务拆分
一次处理多张图时,每张图都必须拥有独立工作区。各自的 tree.json、grid.json 和 legend.json 不能混用。
例如,第一页是总体平面图,第二页是管线详图,第三页是设计说明。回答时必须明确区分:
- "第一页图面显示......"
- "第二页详图显示......"
- "第三页说明文字写明......"
跨图信息只有在确实存在引用关系时才能合并,而且必须注明来源页。不能把第一页的工程名称、第二页的道路和第三页的比例尺混合成一个无来源的结论。
6. 标尺标定与距离计算
只要问题涉及"距离多远、尺寸多少、面积多大",就不能目测,必须先建立像素与实际单位之间的换算关系。
标定依据按优先级选择:
- 图面上的比例尺或标尺;
- 图内已知长度的对象,例如设计说明给出的线路总长;
- 图签中的数值比例,如
1:500,但前提是图像没有经过非等比缩放。
标定结果写入 scale.json:
json
{
"px_per_unit": 3.42,
"unit": "m",
"basis": "图右下角标尺 0---100 m 对应 342 px"
}
其中 px_per_unit 表示每个实际单位对应多少像素。这个例子中:图面上 3.42 个像素对应实际 1 米。
如果两个井之间的中心线长度为 684 px,那么实际距离是200m
如果道路或管线是弯曲的,不能只连接起点和终点,而应沿中心线选取多个路径点。例如:
bash
python measure.py scale.json 120,300 260,300 260,520
这表示从 P1(120,300) 到 P2(260,300),再到 P3(260,520),计算两段折线的总长度。对于弯曲道路,这比用起点和终点之间的直线距离更准确。
量测结果还要说明误差来源,例如:
- 坐标读取通常存在约 ±2~3 px 的误差;
- 比例尺线条本身有宽度;
- 示意图可能不严格等比例;
- 截图或扫描件可能发生非等比变形。
因此,结论应视情况写成"约 200 m"或"约 198~203 m",而不是伪装成绝对精确值。找不到任何标定依据时,只能给出图面相对关系,不能编造实际距离。
7. 第 1 步:图像切分
切分由 split_image.py 完成:
bash
python split_image.py 原图.png \
-o 图拆工作区/任务名/tiles \
--tile 1024 \
--overlap 150
默认把大图切成边长不超过 1024 px 的子图,相邻子图保留 150 px 重叠。
例如,一张 8192 × 4096 的施工图,如果直接输入模型,可能被压缩到长边约 1500 px。小字、细线和符号差异会大量丢失。切成多个 1024 × 1024 的子图后,每个局部都能以更高有效分辨率被识别。
重叠区域的作用是防止元素被切缝截断。假设"中山大道"横跨两个子图:
- 左边子图只包含"中山";
- 右边子图只包含"大道";
- 如果没有重叠,很难确认两个片段是否属于同一个路名;
- 有 150 px 重叠后,该路名通常会在至少一个子图中完整出现。
脚本输出的子图文件名带有坐标,例如:
text
tile_r2_c3_x2616_y1898.png
表示该子图位于第 2 行、第 3 列,左上角在原图中的坐标为 (2616, 1898)。
同时生成 tiles.json,记录每个子图的偏移量、边界框、切分尺寸和旋转角度。后续坐标复原完全依赖这些信息,示例如下:
python
{
"image": "某线路平断面图.png",
"size": [6740, 4768],
"tile": 1568,
"overlap": 150,
"rotate": 0,
"tiles": [
{
"file": "tile_r0_c0_x0_y0.png",
"row": 0,
"col": 0,
"offset": [0, 0],
"bbox": [0, 0, 1568, 1568]
},
{
"file": "tile_r0_c1_x1418_y0.png",
"row": 0,
"col": 1,
"offset": [1418, 0],
"bbox": [1418, 0, 2986, 1568]
}
]
}
工作区隔离
每次任务都会创建带时间戳的新目录,例如:
text
图拆工作区/施工图A_20260903_1530/
本次任务产生的子图、tiles.json、legend.png、legend.json、scale.json、tree.json 和 grid.json 都存放在该目录中。
历史目录一律视为过期缓存,不能复用。否则可能把上一次任务中的路名、比例尺或结构树错误地套到当前图纸上。
8. 第 2 步:图例识别
施工图和地形图大量使用图例。图例可以理解为"符号---含义对照表"。如果不先识别图例,后续看到符号时只能描述外观,无法知道它代表什么。
例如图例可能规定:
- 粗实线代表现状道路;
- 红色虚线代表规划管线;
- 方框内三个圆圈代表接地箱;
- 蓝色三角代表水准点。
流程会优先检查图纸四角、底边和右侧子图,因为图例通常位于边缘或角部,右下角最常见。定位图例后,将块内坐标换算为原图坐标,并裁剪出 legend.png。
随后转写为 legend.json:
json
{
"source": "legend.png",
"global_bbox": [5200, 3600, 6100, 4300],
"entries": [
{
"symbol": "粗实线,线上间隔分布短横",
"meaning": "110 kV 电缆线路"
},
{
"symbol": "方框内三个圆圈,下接接地符号",
"meaning": "接地箱"
}
]
}
图例的作用相当于为整图建立专业词典。后续识别某张子图时,模型可以把"方框内三个圆圈"解释为"接地箱",而不是只记录一个无意义图形。
如果普通截图、网页长图或报表中没有图例,则跳过该步骤,不能强行编造图例。
9. 第 3 步:逐块识别
逐块识别前,使用 stitch_legend.py 将图例拼接到子图旁边:
bash
python stitch_legend.py tile_r0_c0_x0_y0.png legend.png \
-o tile_r0_c0_x0_y0_legend.png
默认把图例等比缩放后拼在子图右侧,也可以放在下方:
bash
python stitch_legend.py tile.png legend.png \
-o tile_legend.png \
--side bottom
这样,模型在识别当前子图时能够同时看到图例。例如,子图中有一条黑色粗线和一个由三个圆圈组成的符号。没有图例时,只能写成:
图中有一条粗线,旁边有一个由圆圈组成的符号。
有图例后,可以写成:
黑色粗线为 110 kV 电缆线路;三个圆圈组成的符号为接地箱。
但符号解释必须有明确出处。只有两种情况合法:
legend.json中有对应图例;- 图面文字直接标注了符号含义。
两者都不存在时,只能描述形状,例如"方框内有三个圆圈,下方接一条竖线",不能根据经验擅自命名为某类设备。
识别输出采用固定 JSON 格式:
json
{
"tile": "tile_r0_c0_x0_y0.png",
"elements": [
{
"id": "e1",
"type": "text",
"content": "滨江大道",
"bbox": [120, 340, 265, 372]
}
]
}
这里的 bbox 必须相对于原子图,而不是相对于拼接后的整张画布。拼在旁边的图例只用于对照,不能作为当前子图内容重复转写。
识别阶段的防幻觉规则
第一,只转写看得见的。看不清的字可以标记为 illegible,并描述可见特征,例如"四字路名,前两字不清"。
第二,数字、型号、桩号和单位逐字符核对。480 m 和 084、YJLW03 和 YJLWOS 只差一个字符,但工程含义完全不同。
第三,不允许根据上下文补全内容。补出来的词往往"看起来最合理",因此也最危险。
第四,不脑补被截断的结构。线条被图框截断时,只记录可见部分;"它应该连到下一页"属于推断,不能写进原文转写。
第五,一旦发现自己"想当然地读出了"完整地名或设备名,但原字迹并不清晰,应回到预检流程,对该区域高清重裁复核。
10. 第 4 步:坐标复原与融合
逐块识别得到的坐标都是子图内部坐标。全局坐标按以下关系计算:
全局坐标=块内坐标+子图左上角偏移量
例如,一个元素在子图中的边界框是:
text
[120, 340, 265, 372]
该子图左上角位于原图的 (1024, 0),那么全局边界框为:
text
[120+1024, 340+0, 265+1024, 372+0]
= [1144, 340, 1289, 372]
坐标复原后,相邻子图中的内容才能放回同一张图。
10.1 重复观测融合
两个相邻子图可能识别到同一段文字。例如:
- 子图 A 识别到"道路全长 1280 m";
- 子图 B 因切缝只识别到"全长 1280 m"。
如果两个边界框在原图中高度重叠、内容一致,就融合为一个元素,保留信息更完整的版本,坐标取两个边界框的并集。
10.2 切断碎片拼接
如果两个文字片段在原图中水平或垂直相接、字体一致、阅读顺序连续,可以拼接。
例如:
- 子图 A 识别到"滨江";
- 子图 B 识别到"大道";
- 两个片段在全局坐标中首尾相接;
- 行高、字体和颜色一致;
- 则可以融合为"滨江大道"。
但拼接必须满足空间条件,不能为了让句子完整而强行缝合。例如,一个片段是 K12+,另一个片段是 300,如果两者在原图中相距很远,就不能直接拼成 K12+300。
10.3 冲突保留
如果两个子图对同一位置给出不同结果,不能选择"看起来更合理"的那个。例如:
- 子图 A 识别为
480 m; - 子图 B 识别为
084。
此时应保留两个候选,标记为 conflict,并记录来源子图。后续通过高清重裁确定结果。
10.4 构造结构树和区域索引
融合完成后,按阅读顺序重新编号:
text
E001、E002、E003......
然后生成两个文件:
tree.json:完整结构树,记录元素编号、类型、内容、坐标和父子关系;grid.json:二维区域索引,记录每个网格包含哪些元素以及区域摘要。
第 4 步的意义不只是"去重"。它把分散在各子图中的局部识别结果恢复为统一的全局结构,使模型能够跨区域比较。例如,要判断"电力管线是否穿越滨江大道",必须同时知道电力管线的路径、滨江大道的位置,以及两者在同一坐标系中的相交关系。没有坐标复原和融合,这些信息只是分散在不同子图中的孤立描述。
下面是一个结构树的案例,会记录到"tree.json"中:
python
{
"image": "某线路平断面图.png",
"size": [6740, 4768],
"grid": [4, 5],
"cells": [
{
"r": 2,
"c": 2,
"summary": "某杆塔、跨越规划道路及相邻档跨越标注",
"element_ids": ["E002", "E003", "E008"]
},
{
"r": 3,
"c": 4,
"summary": "图签区域",
"element_ids": ["E012"]
}
]
}
下面是grid.json的内容:
python
{
"image": "某线路平断面图.png",
"size": [6740, 4768],
"grid": [4, 5],
"cells": [
{
"r": 2,
"c": 2,
"summary": "某杆塔、跨越规划道路及相邻档跨越标注",
"element_ids": ["E002", "E003", "E008"]
},
{
"r": 3,
"c": 4,
"summary": "图签区域",
"element_ids": ["E012"]
}
]
}
11. 第 5 步:基于结构树回答问题
结构树建立后,回答问题不再重新浏览整图,而是:
- 查询
grid.json,定位相关区域; - 找到该区域内的元素编号;
- 从
tree.json读取内容和坐标; - 基于元素编号、坐标和标尺完成回答。
例如用户问:
图中有没有标注该路段名称?
回答流程不是简单地在道路附近找字,而是同时检查:
- 道路中心线附近的标注;
- 图签;
- 设计说明;
- 附属说明;
- 表格中的路段字段。
如果道路旁没有路名,但说明文字中有"本段道路为滨江大道改建段",回答应写成:
图面上未在道路旁直接标注路名;说明文字
E118(x=4210,y=6025)写明:"本段道路为滨江大道改建段。"
这比简单说"图中写了滨江大道"更准确,因为它区分了"图面空间标注"和"附属说明文字"。
回答阶段的防幻觉规则
第一,禁止无中生有。路名、设备名、编号和数字必须来自图面文字、图例或说明原文。
第二,转写和推断分离。content 中的内容是证据;基于证据得到的结论必须明确说明依据。
例如:
E021的图例说明"红色虚线为规划管线",E036显示滨江大道北侧存在红色虚线,因此可以依据E021和E036推断该位置存在规划管线。
第三,位置关系必须用坐标验证。凡是使用"相邻""最近""在右侧"等表述,都要比较两个元素的边界框,而不是凭缩略图印象判断。
例如:
text
E031: [100, 200, 180, 260]
E032: [210, 205, 290, 265]
两个元素水平方向相距约 30 px,可以说它们在图面上接近。若另一个元素距离它们 1800 px,即使缩略图里看起来不远,也不能称为"相邻"。
第四,带有 uncertain、illegible 或 conflict 标记的内容只能作为线索,不能作为唯一结论依据,引用时也不能删除这些标记。
第五,距离和尺寸问题必须走标尺标定流程,给出换算依据和误差说明。
第 5 步的意义在于,把结构树转化为可复用的分析界面。模型不再反复扫描原图,而是通过区域索引定位证据、通过元素编号引用证据、通过坐标验证空间关系,从而减少重复读取,并降低不同轮次回答不一致的风险。
12. 三个附属 Python 工具
12.1 split_image.py:切分与方向校正
该工具是整个流程的入口,负责:
- 按指定尺寸切分大图;
- 保留相邻子图重叠区域;
- 在切分前旋转图像;
- 输出每个子图的偏移和边界;
- 提供文字高度和可读性提示。
典型用法:
bash
python split_image.py 施工图.png \
-o 图拆工作区/任务名/tiles \
--tile 1024 \
--overlap 150
如果图像方向错误:
bash
python split_image.py 施工图.png \
--rotate 90 \
--tile 1024 \
--overlap 150
它输出的 tiles.json 是后续坐标复原的基础。
12.2 stitch_legend.py:图例拼接
该工具把图例等比缩放后拼到子图右侧或下方,让模型识别当前区域时可以对照符号含义。
典型用法:
bash
python stitch_legend.py tile_r0_c0_x0_y0.png legend.png \
-o tile_r0_c0_x0_y0_legend.png
图例只是辅助上下文,不属于当前子图内容。识别结果的 bbox 仍然必须以原子图区域为坐标系,不能因为拼接后画布变大而发生坐标偏移。
12.3 measure.py:标定量测
该工具根据 scale.json 把像素长度换算成实际长度。
校验标定文件:
bash
python measure.py scale.json --check
计算多点折线长度:
bash
python measure.py scale.json 120,300 260,300 260,520
它要求 basis 字段非空,即每次量测都必须说明换算依据。没有比例尺、已知尺寸或可靠比例时,不允许输出实际距离。
13. 总结
图像拆分理解的完整过程可以概括为:
预检方向与清晰度 → 切分并记录坐标 → 建立图例词典 → 逐块精读 → 坐标复原与冲突融合 → 构造结构树 → 基于结构树回答和复核。
它的关键不只是提高局部分辨率,而是把大图转化为有编号、有坐标、有层级、有出处、有缓存的结构化数据。结构树使模型能够跨区域比较、快速定位证据、复用识别结果,并清楚地区分图面原文、图例解释和进一步推断。
因此,这项技能特别适合施工图、地形图等复杂图像:它既保留了局部精读能力,又恢复了全局空间关系,同时通过标尺标定、坐标验证、冲突标记和缓存机制降低误识别与幻觉风险。