largereporter25/compass-globe

GitHub: largereporter25/compass-globe

基于完全开源数据和浏览器端推理的视频地理定位工具,通过 OCR、地名词典和视觉模型将画面中的文字与地标线索转化为可审计的候选地点列表。

Stars: 0 | Forks: 0

# Compass Globe **视频证据的地理位置初步筛选。仅使用开放地理数据。您的视频永远不会离开浏览器。** 放入一段视频。ffmpeg 会提取关键帧,Tesseract 会进行识别——这一切都在您的浏览器标签页内完成。屏幕上的文本会被转化为可审计的位置线索,地名会通过 OpenStreetMap 进行解析,候选区域会显示在地球仪上,并附带每个区域的精确推理过程。 无需 Google Vision。无需 Bing。无需付费的反向图片搜索 API。运行它不需要任何 API key。 **在线演示:** https://compass-globe.vercel.app ![Compass Globe — 在 Sentinel-2 影像上深入至艾哈迈达巴德的街道级别](https://static.pigsec.cn/wp-content/uploads/repos/cas/7b/7bd04db1b2f98f67c6e0eeeaad939d2361946c5519be0dbcdcdda2f2cc2af3ba.png) *一段 12 秒的艾哈迈达巴德路牌片段,经过分析并在 Sentinel-2 无云影像上深入至街道级别。候选列表、推理轨迹和国家锚点均显示在同一个屏幕中。* ## 为什么会有这个项目 事实核查人员仍然在使用 InVID 和 Google Lens 进行视频地理定位。这两种工具的工作原理都是将关键帧分发到 Google、Bing、Yandex 和 TinEye。这会给新闻编辑室带来三种切肤之痛的代价:受频率限制、大规模使用成本高昂,而且每一次查询都会让大型科技公司的搜索引擎清楚地知道你的编辑室当前正在调查什么。 Compass Globe 并不试图复制网络规模的反向图片搜索——除了 Google 之外没人能做到,假装能做到正是这类项目夭折的原因。相反,它解决了一个相邻的问题:**将画面内清晰可读的文字转化为一份有理有据的待排查地点候选名单。** 脚本、路牌、车牌、区号、域名、货币符号。这些都是人类 OSINT 调查人员首先会从画面中读取的信息,现在通过系统化地在每个关键帧上执行此操作,并完好保留推理过程。 大家普遍使用的预训练地理定位模型对全球南方(Global South)的覆盖并不好——StreetCLIP 自己的模型卡片就声明其训练数据完全排除了印度和中国。基于文本优先的 pipeline,结合 OpenStreetMap 和 Mapillary,并不会继承这种数据鸿沟,因为证据是直接从画面中提取的,而不是来自带有西方偏见的训练集。 ## Pipeline 的工作原理 ``` video file (never uploaded) │ ├─ 1. keyframes ───────── Fast: the browser's own decoder, sampled evenly │ Deep scan: real ffmpeg (WASM) scene detection │ ├─ 2. Tesseract.js ────── OCR per frame, in whichever scripts you select │ ├─ 3. CLIP ViT-B/32 ───── landmark and streetscape recognition, in-browser, │ for the footage that has no legible text at all │ ├─ 4. clue extraction ─── deterministic matchers over the recognised text: │ • place-word lexicon (Marg, Chowk, Jalan, Straße…) │ • Unicode script blocks → country priors │ • Indian / UK plate formats → state or country │ • +CC dialling prefixes → country │ • ccTLDs on signage → country │ • currency signs → country │ • capitalised tokens → possible place names │ ├─ 5. country anchor ────────── script, plate, dialling code, ccTLD *and* │ CLIP streetscape signatures fix a country │ ├─ 6. OpenStreetMap Nominatim ─ place names resolved *inside* that country │ ├─ 7. KartaView + Panoramax + Mapillary ─── street-level imagery near the lead candidate │ ├─ 8. SIGINT overlays ───────── GPSJam (ADS-B-derived GNSS interference) + │ OpenSky (live aircraft) for the top candidates │ ├─ 9. weighted aggregation ──── ranked candidates + confidence band │ ├─ 10. globe + reasoning trail ─ every candidate shows the clues that produced it │ └─ 11. Shadowline ────────────── solar geometry turns a shadow direction into a time-of-day window ``` ### 视觉通道 —— 针对没有文字的视频 大多数疯传的虚假信息视频都没有可读的路牌。在那里,纯文本的 pipeline 会遇到瓶颈,因此 Compass Globe 通过 transformers.js 在浏览器中运行了两个开源的对比 模型,并根据 `lib/visual-priors.ts` 中的两个 prompt 库对每个关键帧进行评分: - **地标** —— 具有真实坐标的独特人造建筑。在这里 匹配到结果是该工具能生成的最强线索,因为它指向的是一个具体的地点 而不是一个区域。门槛被刻意调高:错误的地标匹配是 该工具可能输出的最具误导性的内容,因为它看起来像 是确定的结果。 - **街景特征** —— 自动人力车和架空线缆、卡其色 警服、拉线式交通信号灯、高架铁路桁架、马塔图小巴、踏板车密度、卡车艺术。单独 看没有任何一项是决定性的。关键是它们是**无地名辞典的**,因此它们能像 车牌前缀一样精确地锚定一个国家——这正是让完全没有文字的视频也能被定位的基础。 一个负向 prompt 库(模糊的帧、人脸、空白墙、新闻演播室)与它们 并存,因为如果没有这些平淡无奇的选项来分散注意力,某个地标总会在一帧空无一物的画面中“胜出”。 整个库的文本嵌入只计算一次并被重复使用;每个关键帧 生成一个单一的图像嵌入,剩下的就是计算余弦相似度。这使得在 笔记本电脑 CPU 上运行包含 200 个 prompt 的库依然可行。权重从 Hugging Face CDN 下载一次后被缓存——图像永远不会离开标签页。 第二个模型,Google 的 **SigLIP**(base patch16-224,Apache-2.0),在 相同的 transformers.js 运行时环境中与 CLIP 一起运行。它的错误与 CLIP 不相关,因此两个模型针对每个 prompt 的概率分布会被平均化 为一个综合得分。只有当*两者*都倾向于同一个结果时,地标的阈值才算被跨越,这是刻意保守的做法——错误的地标匹配是 该工具可能输出的最具误导性的内容。如果 SigLIP 加载失败,该步骤 将退回到仅使用 CLIP,开关上也会予以提示。 **已测试:** 一段完全由 Jantar Mantar 照片构成、任何帧中都没有可读 文字的视频,返回的排名前两位的候选结果是*Jantar Mantar, New Delhi* 和 *Red Fort, Delhi*,并锚定到印度。两者都是红砂岩莫卧儿时代的 德里建筑,因此将它们混淆是情理之中的。 这是一个**第二意见,在 UI 中被清晰地区分开来**。这两个模型 经常表现得异常自信且得出错误结论。视觉通道可以被完全 关闭。 ### 地名词典 拉丁字母 OCR pipeline 中最大的盲区是那些是拉丁字母但 非英语的文本。“Sansad Marg”、“Karol Bagh”、“Jalan Sudirman”、“Prospekt Peremohy” 全都是纯拉丁字符,因此脚本检测器什么也不会说——然而 这些词本身就是决定性的。 `lib/lexicon.ts` 匹配约 30 个语系的街道和行政词汇:印度后缀(*marg, chowk, nagar, vihar, bagh, ganj*)、 行政术语(*thana, tehsil, mandal*),以及它们在德语、 法语、西班牙语、葡萄牙语、土耳其语、马来语、泰语、斯瓦希里语和其他语言中的对应词。它还 包含孟加拉国、巴基斯坦、南方共同市场、 荷兰、德国、土耳其和阿联酋的车牌版式,以及最初的印度和英国 模式。 这些匹配**绝不依赖地名辞典**,因此像车牌前缀一样,它们可以 在不继承 OSM 地图密度偏差的情况下锚定一个国家。 **已测试:** “Sansad Marg” / “Karol Bagh Police Chowki”——没有任何英语地名 也没有任何非拉丁字母——现在产生了三个词典匹配,以 100% 的置信度锚定到 印度,并在 Central Delhi 解析出 Karol Bagh。在此之前,这些 词都没有携带任何信号。 ### 这个地球仪是一个真实的地图 不是一个风格化的球体。地球仪加载实时的瓦片并可以 深入到街道级别,因此可以针对实际图像来检查候选区域,而不仅仅是图表上的一个点: | 图层 | 来源 | 许可证 | | --- | --- | --- | | 卫星图 | NASA GIBS — MODIS Terra 每日真彩色 | NASA 开放数据,无需 key | | VIIRS | NASA GIBS — NOAA-20 VIIRS 每日真彩色 | NASA 开放数据,无需 key | | Sentinel-2 | EOX Sentinel-2 cloudless(2016/2017 镶嵌图) | CC BY 4.0,无需 key | | Esri | Esri World Imagery(Maxar, Earthstar Geographics) | 免费但需署名,根据 Esri 条款**仅供非商业用途** | | 街道图 | OpenStreetMap 标准瓦片 | ODbL | | 地形图 | OpenTopoMap,基于 SRTM 高程数据 | CC BY-SA | 默认的 `Satellite` 图层是实时的 NASA GIBS(每日更新,~250 m 分辨率),而不是 冻结的镶嵌图。GIBS 瓦片被固定在几天前的 UTC 日期,因为 其 EPSG:3857 REST endpoint 在 `default` 时间 token 上会报 404 错误。如需更清晰的、 无云的静态底图,请使用 `Sentinel-2`;如需最高分辨率的街道 细节(或者需要在一个候选点读取路面级别信息时),请在下降前切换到 `Esri` 或 `Sentinel-2`——GIBS 250 m 的分辨率最高只支持缩放到级别 9。 选中候选点会将镜头平滑过渡到区域海拔高度;**深入至街道级别** 会将其下降到大约一公里的高空,距离足以看清道路布局 并将其与关键帧进行比对。每个候选点还带有直达 OpenStreetMap、OSM 轨迹视图以及 Bhuvan(用于印度坐标)的链接。 ### WebGPU 在浏览器支持的情况下,CLIP 过程会在 WebGPU 上运行,并在 其他所有环境下静默且自动地回退到 WASM。当前的后端会显示在视觉功能的开关上。transformers.js 作为原生 ES module 从 CDN 加载,而不是打包在本地——它的 ONNX runtime 使用了 `import.meta`,这会被 Next 的 压缩器拒绝,并且将推理 runtime 留在主 bundle 之外 意味着对于关闭视觉功能的用户,应用依然可以瞬间加载。 ### 国家锚定 —— 这个功能存在的原因 OpenStreetMap 的地图绘制并不均匀。西欧的命名 地物远远多于南亚、非洲或拉丁美洲,因此从 路牌上读取到的一般 token 默认会偏向西方解析。测试中的一个真实案例:在新德里 Jantar Mantar 拍摄的视频,能清楚地看到“Delhi Police”,但系统却将 **Westminster, London** 排在第一位——因为在查询“Delhi”之前,“Parliament Street Station”先匹配到了 伦敦的一个地物。 有三件事修复了这个问题,而这正是玩具和工具之间的区别: 1. **首先从无偏见的证据中锚定国家。** 文字系统、车牌 前缀、区号、ccTLD 和货币符号都不带有地名辞典的偏差。如果 它们以明显的多数指向同一个国家,该国家就会成为锚点。 2. **在锚点范围内查询。** 调用 Nominatim 时会传入 `countrycodes=`,这样 “Parliament Street”就会解析为新德里的 Sansad Marg,而不是伦敦。 3. **降级冲突,而不是删除。** 锚点之外的候选点会保留在 列表中,并标记为 `conflicts`,权重缩减至 18%,因为 锚点可能是错的,隐藏其他选择是不诚实的。 除此之外,地名提取器现在会丢弃那些有一半或以上的词属于 一般性市政词汇的短语——“Commissioner Office”、“Traffic Marshal Point”、“Police Control Room”——并将其有限的查询预算优先花在 单一且独特的专有名词上。在德里的测试中,这把 32 个无用的 地名减少到了 2 个有用的,并将最高结果从伦敦移到了新 德里。同一视频片段的纯文本版本现在可以直接浮现出 **Jantar Mantar Astronomical Observatory**。 ### 两种提取模式 **快速提取(默认)** 驱动浏览器自带的视频解码器——寻找一个隐藏的 `
标签:OCR文字识别, 事实核查, 本地音视频处理, 浏览器端应用, 自动化攻击, 视频地理定位