Administrator
Published on 2026-08-20 / 3 Visits
0
0

图像地理定位的证据链:几何约束、CUDA 搜索与独立复核

一张没有 EXIF 的岛屿照片,能否只靠几何和公开数据找到拍摄地点?

2026 年 8 月公开的一份技术复盘给出了完整案例。作者把照片中的三座岛转成角度和距离比,在全球陆地多边形里生成约 8070 万个三元组,用 CUDA 做并行筛选,再叠加岛形、植被和高程条件,最终把候选缩到 26 个。人工查看卫星图后,答案指向密克罗尼西亚联邦楚克州的 Oan Resort。

这个案例真正值得复用的部分是证据链。计算负责生成和收缩候选,独立证据负责把候选提升为结论。两者之间需要保留可复算的中间产物。

证据核验日期:2026 年 8 月 20 日。本次检查了原题、原作者复盘、GitHub 仓库提交 fbca30683357333682c749bc402127a56a2bbc34、公开候选文件、数据源官方说明和一份独立 walkthrough。没有下载约 880 MB 的地理数据,也没有在 CUDA 环境重跑完整管线。

阅读时间:约 10 分钟 · 全文约 3800 字

核心结论

  • 搜索前先冻结原图、坐标约定、选点、误差带、数据版本和代码提交。搜索过程中调整条件时,需要留下变更记录。
  • 每个视觉判断都要转换为显式条件。每一级候选集都要落盘,后续才能检查真值在哪一步被保留或误删。
  • 仓库文件可以直接核验 948、213、137、26 四级候选数量。更早的 8070 万三元组、158784 个 GPU 命中、204.1 ms kernel 时间和 66 个 NDVI 存活项属于作者报告,公开仓库缺少同强度运行日志或中间文件。
  • 独立球面计算复现了最终候选的 324.97° 方位角、31.25° 夹角和 0.6903 距离比。
  • Oan Resort 官方站与独立 OSINT walkthrough 从另一条路径支持相同地点和西北方向。独立 walkthrough 的坐标与仓库 P0 相距约 85 米。
  • 整条管线包含大量启发式。CUDA 提高搜索吞吐量,视觉假设与阈值仍需独立验证。

先定义结论合同

OSINT Exercise #004 原题要求回答三个问题:度假村名称、岛屿坐标和相机朝向。目标很清楚,但要形成可复查的调查,还需要一份更严格的结论合同。

搜索前至少保存六类工件:

工件 最小内容
原始材料清单 原始 URL、获取时间、文件哈希、尺寸、元数据输出
观察记录 哪些对象被标为 P0、P1、P2,像素坐标和选点误差
搜索规格 经纬度顺序、单位、公式、阈值和排除条件
数据清单 数据集名称、版本、许可、下载日期和哈希
执行清单 代码提交、依赖、硬件、命令和抽样规则
决策账本 各级候选数量、淘汰原因、反证和最终外部核验

原作者的 GitHub 仓库已经覆盖了大部分执行层:分阶段 Python 脚本、CUDA kernel、四份候选 JSON 和最终 HTML 报告都可以读取。

仓库仍缺少几项关键输入:原图的指纹 JSON、约 880 MB 的陆地多边形数据、NDVI 阶段 JSON 和完整运行日志。因此,公开材料支持代码审计和部分中间产物核验,尚未形成一次开箱即得的端到端复现实验。

代码存在、代码运行过、他人在冻结输入上复现成功,属于三个不同证据等级。

把照片编译成约束

作者先在照片中选择三块陆地:

  • P0:前景中的度假村小岛;
  • P1:右侧岛屿;
  • P2:左侧、带山峰的岛屿。

点击工具记录三个像素点,计算 P0 处夹角和两条边的长度比。由于无人机高度、相机俯仰、镜头参数和岛屿中心都未知,作者给两个数值增加了 ±20% 的容差。

这一步相当于一个假设编译器:

视觉观察
→ 三个带标签的像素点
→ 夹角窗口与距离比窗口
→ 机器可执行的候选判定条件

它的价值在于把感觉变成了可检查字段。误差也很明确:图像平面几何只是地面几何的近似。更严格的做法是让不同观察者重复选点,记录方差,再用多组相机投影假设做敏感性分析。候选只有在合理扰动下持续存活,稳定性才足够高。

先缩小空间,再调用 GPU

OpenStreetMap Land Polygons提供全球陆地区域的 WGS84 Shapefile,也提供拆分大多边形的版本,便于程序处理。拆分后的多边形是计算切片,不能直接等同于一座真实岛屿。代码仍把每个切片质心当作独立 landmass 点,因此大陆沿岸和切片边界附近可能出现人工邻居。原作者基于这套数据逐层过滤:

阶段 条件 输出与证据状态
热带纬度带 纬度 -30° 到 +30° 141131 个多边形,作者报告
局部密度 5 km 内邻居不超过 10 个 51576 个点,作者报告
邻近聚类 20 km 内至少三个点 23500 个簇,作者报告
三元组生成 每簇最多 60 点,再枚举三点组合 80690777 个三元组,作者报告
CUDA 几何掩码 角度、距离比、直径、间距和边长窗口 158784 个原始命中,作者报告
去重 相同 P0/P1/P2 只保留一项 8915 项,作者报告
开阔水面矩形 画面空白侧不能出现额外陆地 948 项,仓库可核验
珊瑚岛形态 紧凑度和附近微型沙洲 213 项,仓库可核验
椭圆形态 长宽比和最小外接矩形填充率 137 项,仓库可核验
NDVI P0 的 NDVI 不低于 0.6 66 项,作者报告,阶段文件缺失
高程 P0 较低,镜头前方存在 100 到 500 米地形 26 项,仓库可核验

这套顺序比任何单个公式更重要。便宜的空间条件先缩小问题,组合爆炸出现后才把高度并行的三元组判断交给 GPU。需要远程访问 Sentinel-2 的 NDVI 被放到后段,30 米 Copernicus DEM 高程采样则继续处理已经收缩的集合。

这里应用的是瓶颈分析:算力只有在候选判定已经足够小、足够明确、可以并行时才真正产生价值。

CUDA 能证明什么

CUDA kernel 给每个候选三元组分配一个线程。线程按陆地多边形面积排序,把最小项视为 P0,再用二维叉积确定 P1 与 P2 的顺序,最后检查夹角、距离比、P0 直径、相对间距和两条边长。

原文报告,在 RTX 3050 上,约 8070 万个线程占用 5169 MB 显存,kernel 执行时间为 204.1 ms。本次能够核验代码和下游候选文件,无法独立核验这组三个运行数字,因此文章把它们保留为作者报告。

kernel 实际证明的命题很窄:

给定当前三元组集合和阈值,输出项满足代码实现的判定条件。

它无法验证热带假设、P0 标签、±20% 容差、每簇 60 点抽样,以及图像几何能否代表地面几何。一个未经验证的条件同样可以在 GPU 上跑得很快。吞吐量和证据强度需要分开记录。

独立复算最终几何

26 项最终候选中的第 8 项是:

P0 = (7.363300, 151.755983)
P1 = (7.386573, 151.739534)
P2 = (7.379860, 151.717975)

使用独立大圆距离和初始方位角公式复算:

  • P0 到 P1 方位角:324.973°;
  • P0 到 P2 方位角:293.720°;
  • 两个方位之间夹角:31.253°;
  • P0 到 P1:3.160 km;
  • P0 到 P2:4.578 km;
  • 两段距离之比:0.69031。

仓库记录为 31.25° 和 0.6903,原文把 324.97° 归为西北。复算结果与公开记录在有效精度内一致。

当前 OpenStreetMap 的 Oan 海岸线对象还提供了一次数据层核验。按其 v11 闭合多边形计算,质心为 7.3632996°N, 151.7559827°E,与仓库 P0 基本一致。这个点代表岛屿质心,不代表度假村建筑或相机位置。

地点身份还有另一条独立路径。Oan Resort 官方站可以确认度假村名称。一份 2024 年独立 walkthrough使用反向搜图和 Google Earth,给出 Oan Resort 坐标 (7.3626, 151.7563),并判断镜头朝西北。该坐标与仓库 P0 约相差 85 米。

精确航向的不确定性高于八方位结论。高程阶段用 P1 与 P2 方位的短弧平分线 309.35° 作为镜头前方,最终答案则使用 P0 到 P1 的 324.97°。两者都属于西北,因此 cardinal direction 仍然成立,管线没有严格确定精确航向。六位小数坐标也应理解为岛屿尺度候选点,而非亚米级相机位置。

两条路径的机制不同:

  1. 几何约束和全球候选搜索;
  2. 图像身份、地图位置和视觉朝向。

两者收敛到同一个地点,可信度高于单独使用其中任何一条。

每个启发式都要进入失败账本

这条管线成功找到了答案,同时也暴露出真值可能在哪些环节消失。

透视与选点

相机高度、俯仰角、视场角和镜头畸变未知时,三个像素点无法唯一确定地面三角形。容差带只能吸收部分误差。验收时应重复选点、改变投影假设,并统计最终候选的存活稳定性。

不完备的簇内抽样

超过 60 点的簇会按多边形面积分层抽样。这样可以控制组合数量,也意味着搜索空间不完备。记录抽样前后点数、规则和随机状态,并用不同抽样策略复查最终候选。

经纬度近似

聚类代码直接在经纬度平面上用 km / 111 查询 KD-tree。经度对应的实际距离会随纬度变化。后续 CUDA 计算加入了纬度余弦修正,前面的邻域搜索没有。在纬度 30°,这种写法的东西方向覆盖只有目标物理半径的约 86.6%,处在阈值边缘的点可能被提前排除。

面积、周长、直径、紧凑度和椭圆指标同样直接在 EPSG:4326 经纬度上估算,没有统一投影到局部等距或等面积坐标系。最终候选位于 7.36°N,局部误差较小;整个 ±30° 搜索带里的误差会随纬度和形状朝向变化。

卫星场景选择

NDVI 脚本调用 Element 84 的 Earth Search STAC API,筛选整景云量低于 20% 的 Sentinel-2 L2A 场景,并设置 limit=1。代码没有指定日期范围或 sortby,也没有检查目标像元的云和阴影质量掩码。因此只能声明使用 STAC 返回的第一个匹配场景,无法声明它一定是最新且目标像元清晰的影像。

NDVI 公式本身有权威依据。USGS给出的标准公式是 (NIR - Red) / (NIR + Red)。0.6 阈值属于本案例的启发式,需要与场景 ID、获取时间、云量、波段值和采样像素一起保存。

高程与缺失状态

Copernicus DEM 官方说明将 GLO-30 定义为全球 30 米数字表面模型,其中可能包含建筑与植被表面。代码采样 P0,并在镜头前方用 11 个方向乘 7 个半径取得 77 个点。20 km 处相邻射线约相隔 3.5 km,细窄高地可能被漏掉。P0 tile 缺失时,数组默认值仍为 0 米,这会放宽低岛条件。生产流程应把 missing 作为独立状态,任何必需测量缺失时都停止晋级。

最后的人工目视

26 项候选最终由人逐一打开卫星图检查。目视复核属于另一种证据机制,但完整审计仍需保存观察者、判定标准、截图时间和每个淘汰项的理由。只保存正确答案,会丢失最有价值的负证据。

一套可复用的 OSINT Agent 验收协议

这套案例可以抽象成七道门。

1. 保全

保存原文件哈希、元数据结果和工作副本,记录每次转换。Berkeley Protocol提供了数字开源调查在识别、收集、保存、验证、分析和呈现方面的通用框架。

2. 形式化

把每条观察转成字段、单位、容差和理由,并标注它属于测量、推断还是假设。

3. 生成候选

用宽松、便宜的条件生成候选,完整保存输出和数据清单。候选阶段追求召回率,不能提前包装成结论。

4. 分层过滤

每一级只执行一个命名清楚的条件。存活项保留导致通过的数值,淘汰项保留机器可读原因。

5. 压力测试

改变选点、阈值、簇内抽样、卫星日期和距离算法。一个地点如果只在某组窄参数下存活,它仍是脆弱候选。

6. 独立交叉核验

换一种机制验证:反向搜图、官方机构或商家信息、街景或卫星图、另一数据集、另一位调查者。两个底层共享同一地图数据库的服务,不应直接算作完全独立。

7. 按证据等级发布

等级 可以声明的内容
观察 图像中存在三块表观陆地,选点如下
候选 某地点满足已实现的几何条件
存活候选 该地点也通过声明过的岛形、植被与高程条件
已交叉核验地点 不同机制支持相同地点和朝向
已复现结果 独立环境从冻结输入完整重跑并得到同一结果

本案例达到已交叉核验地点。公开中间文件、独立数学复算和外部地点证据都较强,完整独立重跑仍是下一等级。

常见问题

没有 EXIF 或 GPS,照片还能定位吗?

可以。视觉几何、物体身份、地形、植被、阴影、文字和地图要素都能用于生成与排除候选。输出需要同时携带置信等级和可审计假设。

GPU 会让图像地理定位更准确吗?

GPU 让可并行条件执行得更快。准确性取决于观察、候选覆盖、公式、阈值、数据质量和独立核验。

图像地理定位证据链应包含什么?

至少包含原文件哈希、元数据输出、观察坐标、假设、阈值、数据版本、代码提交、执行命令、中间候选集、淘汰原因、独立佐证和不确定性说明。

负证据怎样记录?

记录候选地点、失败条件、测量值、阈值、数据源和缺失状态。后续调查者只有拿出新机制或新证据,才有必要重新打开这条路径。

什么时候应该只给区域,而不该给精确坐标?

当合理改变选点、投影、阈值或数据集后,结果会在多个地点之间切换,就应发布区域或候选集合。不同机制都收敛到同一位置后,精确坐标才获得足够支持。

参考资料

延伸阅读:数学 Agent 的双循环协议:把开放探索与可信知识分开。图像定位同样适用这条边界:候选生成可以开放探索,可信结论必须经过独立验证门。


Comment