趁热打铁
很早就听说过锁眼卫星(KeyHole)——1960到1984年间,美国国家侦察局发射了KH-1到KH-9十余代侦察卫星,用胶片返回式:卫星在轨拍摄,胶片密封进返回舱扔回地球,C-130在空中用钩子捞。分辨率从早期7.5米进化到KH-7的0.6米。在Landsat-1(1972年,80米分辨率)升空之前,这是地球上唯一能从太空高分辨率记录地表的手段。1995年起分三批解密,约93万帧由USGS免费公开。
但一直没动手。原因很简单——资料太少。虽然USGS官网上挂着下载入口,但具体怎么操作、Token怎么配、API权限怎么申请,几乎没有清晰的教程。国内但凡能搜到的相关文章,要么是商业遥感公司的广告,要么是学术论文中寥寥几行带过。整个流程像一个黑箱,外面的人只知道有这么个东西,但真要动手毫无头绪。
上次折腾民国五万分之一地图,从德国马普研究所前端,挖出一条跨国的数据链路,最后拼出一张312MB的日照民国地形图——关键是,整件事是和AI搭手干完的。那我就在想:同样在海外服务器上、同样是免费公开的历史影像,既然民国地图这条路走通了,锁眼卫星能不能也让AI来搞定?
第一步:只有一个数据源
首先需要明确一件事:锁眼卫星影像没有镜像站,没有替代源,没有国内分发节点。它是美国政府的冷战军事资产,原始胶片保存在国家档案馆(NARA),数字副本仅由USGS统一分发。全球只有一个下载入口:
https://earthexplorer.usgs.gov/
其他声称能提供锁眼影像的国内平台,本质上都是中间商——他们从USGS下载,做几何校正,然后转手卖给用户。
USGS将解密数据分为三个数据集:
其中KH-4B(1967-1972,1.8m分辨率,双相机立体成像)是应用最广的主力型号,也是本文下载的核心目标。
第二步:注册、Token与权限迷宫
下载的第一步是注册USGS EROS账号。浏览器打开 https://ers.cr.usgs.gov/register,仅需用户名和密码(无需邮箱验证),2分钟搞定。
但注册完不等于能下载。USGS在2024-2025年间改版了M2M(Machine-to-Machine)API的认证方式——不再接受密码直接调用API,而是要求生成一个Application Token:
Token 可以让你查询数据(scene-search),但不能下载。下载需要额外申请 Machine-to-Machine 下载权限:
审批通过后,Token 自动获得 download-options 和 download-request 权限。至此,API 自动化的所有前置条件就绪。
第三步:检索日照的覆盖范围
以日照市为例。先在EarthExplorer上设定搜索范围——日照市区大致位于 35.0°-35.8°N, 118.8°-119.8°E。在 Search Criteria 页面切换到 Decimal 模式,逐一添加四个角点坐标:
勾选 Declass 1 数据集,点 Results,返回 638 景。这些影像拍摄于1960-1972年间,以KH-4A和KH-4B为主——其中KH-4B的1.8m分辨率足以看清城市道路、街区轮廓和农田边界。
其中约71景已经完成数字化扫描,标记为"Download Available",可以直接免费下载;其余567景虽然目录可见,但胶片尚未扫描,需要提交On-Demand处理订单($30/景),由USGS手动扫描后释放。
第四步:API批量下载
拿到M2M下载权限后,整个流程可以通过Python脚本全自动完成。核心Auth流程:
关键陷阱:download-options 返回的 id 字段才是 productId 的正确值,不是 productCode。AI在这个坑上浪费了一小段时间。
下载结果:
第五步:原始数据的"原罪"
下载完打开第一张图,你大概率会困惑——黑乎乎的、没有经纬度、甚至方向都不对。这不是下载错了,而是锁眼影像的天然特征:
① 无地理坐标:Corona卫星使用胶片返回式方案——拍摄时没有任何GPS或IMU数据,返回舱回收后冲洗出的胶片上只有画面,没有经纬度。USGS数字化扫描时只在目录中记录了估算的四角坐标。这意味着每张TIFF打开后就是一个无参照的矩形像素矩阵。
② 全景相机畸变:KH-4A/4B使用推扫式全景相机,成像几何是典型的"蝴蝶结"变形——影像边缘被压缩,线状地物弯曲。这种畸变不是简单的旋转或仿射变换能解决的。
③ 黑白单波段:胶片只有全色感光层,没有多光谱信息。不能做NDVI、不能做地物分类。它的价值在于空间分辨率和历史唯一性,不在于光谱分析。
④ 云量不可控:1970年代的任务规划只为军事侦察服务,没有云量筛选这回事。部分影像可能有50%以上的云层遮挡——纯看运气。
第六步:几何校正——从"裸片"到可用数据
校正分为两阶段:粗配准(批量化,自动化)和精校正(逐景手动GCP)。
阶段一:粗配准——用USGS四角坐标赋初始地理参考
USGS为每景影像提供了估算的四角经纬度(源自卫星轨道推算,非实测)。虽然精度只有几百米到几公里,但足够把影像"放到地球上大致正确的位置"。用 rasterio 写入 GeoTIFF:
这一步处理了全部71景的266个TIFF分片,生成57.9GB带WGS84坐标的GeoTIFF。GIS软件里直接拖入,影像会自动定位到日照附近。
阶段二:精校正——GIS软件逐景控制点配准
粗配准后的影像误差在几十到几百米量级,道路、海岸线和现代底图有明显偏移。精校正的步骤:
1. 选择参考底图:在GIS软件中加载卫星影像作为参考层,GIS软件我用的是Bigemap(虽然AI推荐我用QGIS)。对于1960年代的数据,优先选择变化最小的地物作为控制点——河流交汇处、海岸线凸角、山脊线分水岭,避免城镇建筑(变化太大)。
2. 基于控制点位校准:Raster → Georeferencer → 打开粗配准后的TIFF。在Corona影像和参考底图之间选取同名的地面控制点(GCP),建议每景至少选8-12个点,均匀分布而非集中在角落。
3. 输出:重采样方法选Cubic(平滑),输出分辨率设为与原始扫描相当(约1-2m/像素),导出为GeoTIFF。
影像里的日照
精校正后的影像拿到手,最先看的当然是和自己有关系的几个地方。
跨越六十年的对视

图1 1964年6月21日锁眼卫星影像与今日谷歌地图匹配对比
这是1964年6月21日某帧锁眼卫星影像,和今天日照市的谷歌地图做匹配对比。短短六十年,这片土地上发生的变化是翻天覆地的。许多河流被加固取直、道路基本完全翻新、甚至部分海岸线都变了形状——想在两张图上找到共同的锚点,远比想象中困难。
最后能靠得住的,只有几处六十年间几乎未变的地标:任家台、桃花岛等尚未大规模开发的海岛,以及1960年代前就已建成的日照水库和马陵水库。以它们为锚点,才勉强把两张跨越一个甲子的图拉到了同一个坐标下。
当时的日照县城


图2 日照老城区——当年的日照县城
这是日照老城区,当时还叫日照县。县城面积不大,仔细看甚至还能辨认出老城墙的大致轮廓。城西的抗日烈士纪念塔非常显眼,往西一里地、路北边,能找到当时的尧沟村。城东的营子河、后楼河、香河也清晰可辨。日照县城往北,过了营子河就是日照一中。
新市区与石臼所


图3 日照新市区一带——石臼所、万平口与沙墩河
这里是今天日照新市区的所在,但60年代基本还是一片未开发的土地,没有太多明显的地标。在整个画面里,建成面积最大的聚落是石臼所。日照港尚未修建,海岸线保持着比较自然的状态。
沙墩河很细,但弯弯曲曲的走向倒也好辨认——跟今天被人工重新塑造过的笔直河道相比,判若两河。万平口也很显眼,不过六十年间也发生了巨大的变化。
苏家村一带


图4 苏家村附近的乡村肌理
苏家村附近,60年代完完全全是乡村。没有高楼、没有水泥路,只能靠任家台、桃花岛、丝山这些非常显眼的海岸线和山体来做空间定位。
苏家村的细节


图5 苏家村——放大后的影像细节
把苏家村周边放大,能看到周围几个村庄的分布,以及今天秦刘路的前身——一条田间小道。当时的苏家村还非常小,村庄尚未发展到秦刘路上。
另外注意看苏家村南边,紧挨着一条小河。但现在那条河的位置在更南边。跟父亲求证,70年代这里发过一场洪水,河道整体往南移了一段——如果不是锁眼影像留下了改造前的画面,这种级别的微观地貌变化,根本无从知晓。
技术复盘
这次操作验证了一条完整的"历史遥感数据复活"链路:
几个值得记住的点:
1. 唯一源,别绕弯:锁眼影像全球只有USGS一个分发点。没有镜像、没有BT种子、没有网盘。花时间找替代品不如花时间搞定API权限。
2. M2M权限分两层:Token登录只能查不能下;download权限需要单独申请,理由写清楚科研用途就行,审批很快。
3. Corona不是正射影像:它是全景相机胶片扫描件,有显著的蝴蝶结变形。校正不能用简单的多项式——必须上TPS或类似的非线性算法。
4. 粗配准省不了:266个TIFF手点GCP不现实。先用USGS四角坐标批量化粗配准,把所有影像放到大致正确的位置,再挑重点场景精校。
5. 立体像对是隐藏宝藏:KH-4B的双相机(前视+后视)提供立体覆盖。如果你需要生成1960年代的DEM,这份数据是唯一的选择。
当AI开始挖卫星数据
下载、配准、分析这一整套流程,是和AI工具搭档完成的。以下是这次协作中的关键对话片段。
我:帮我下载一下日照市的锁眼卫星数据,你先跟我说一下你能获取到的数据来源及质量,我再确定是否下载。
AI:根据调研,以下是日照市锁眼卫星数据的完整情况。USGS EarthExplorer是唯一免费数据源,分三批解密:Declass 1(KH-1~KH-6,1960-1972,1.8m)覆盖最全,Declass 2(KH-7,0.6m)分辨率最高,Declass 3(KH-9 Hexagon)补充性数据。日照作为山东沿海城市,三批数据集大概率都有覆盖。但原始数据是黑白胶片扫描,无地理坐标,需手动配准。要我先在EarthExplorer上实际检索吗?
我:继续。
AI:USGS M2M API 端点有变化,让我直接用浏览器操作 EarthExplorer。先初始化浏览器,打开EE页面填坐标——日照四角:35.8N/118.8E, 35.8N/119.8E, 35.0N/119.8E, 35.0N/118.8E。Declass 1返回638景!但Results页面的按钮是div伪按钮,Playwright点不了。改用xbrowser CDP直连……坐标搞定了,Results页面也加载了,但Export CSV被overlay挡住。
我:你自己想办法解决。
AI:M2M API的login-token权限不够,download返回403。需要额外申请Machine-to-Machine下载权限——就是ERS里的Access Request。申请理由填科研用途,1-2天就批。半天就批下来了!现在download-options返回200,71景可直接下载(54.1GB),567景需On-Demand订购。正在批量下载,5/71完成…62/71…全部71景下载完了!53.3GB。
我:打开看了一下,没有经纬度,分辨率好像也不够高。
AI:正常。Corona是胶片返回式卫星,没有嵌入地理位置。不同任务分辨率差异大:KH-1~KH-3约7.6m,KH-4A约2.7m,KH-4B约1.8m——你手里的47景KH-4B才是主力。建议用rasterio先批量粗配准(USGS四角坐标),再QGIS逐景精校正。
我:先粗配准,后面我来做精校正。
AI:用rasterio写入WGS84地理参考,71景×266个TIFF分片全部完成,57.9GB GeoTIFF。验证了一景:DS1103-2110DA110_a.tif,EPSG:4326,范围 116.35-118.80°E, 35.20-35.23°N,31613×11060像素。QGIS直接拖进去就能定位到日照区域。精校正你后续用QGIS Georeferencer,变换选Thin Plate Spline,参考底图用Esri World Imagery就行。
写在最后
1964年6月21日,一颗锁眼卫星以150公里的轨道高度飞越山东半岛上空。它的全景相机扫过日照的海岸线、县城、农田和村庄,胶片随后被密封进返回舱,从太空坠落,在大气层中被C-130运输机用钩子捞回。
62年后,这张胶片从USGS位于南达科他州的数字化扫描仪中流出,穿过太平洋光缆,以不足1GB的数据包抵达一台PC电脑。经过几次简单的坐标写入和TPS变换后,化作一张可与现代GIS完美叠加的底图。
这是属于这个时代的"考据"——不是去档案馆翻找泛黄的纸页,而是握住一条从冷战侦察卫星出发、经过千禧年解密、最终抵达开源GIS的数据链路。然后,在一个3万像素宽的GeoTIFF里,看见了20世纪60年代的日照。
夜雨聆风