
2026/08/19 21:19
幾何とCUDAプログラミングによるランダムな島の位置決定
RSS: https://news.ycombinator.com/rss
要約▶
日本語訳:
本文は、Sofia Santos が Challenges Gralhix の第 4 号を成功裏に解決した過程を詳述しています。同課題では、マージャンの座標(緯度 7°21′48.4″N、経度 151°45′20.7″E)およびカメラが北西方向(方位角 324.97°)を向いているリゾート「Resort Oan」が特定されました。この解決策は、Google Lens といったプロプライエタリツールを使用せず、完全に数学的モデル링とオープンソースデータに依存していました。
WEBP 画像(サイズ 736x512)には EXIF または GPS データが含まれておらず、チームは 3 つの陸地masses(P0 は島嶼、P1 は右側の島、P2 は左前側の山岳島)に基づく幾何学的フィンガープリントを用いて相対距離と角度を計算しました。
main.png のメタデータ解析の結果、EXIF および GPS データは検出されず、画像形式は WEBP でサイズは 736x512 と判明しました。
厳密なプロセスにより、多数の制約条件下で何百万もの候補照合がフィルタリングされました:熱帯緯度制限(-30°から30°)、局地的密度(5km 以内の近隣が10点未満)、およびクラスター化(20km 以内に3点以上)。サンプリングではクラスター数を60点まで制限し、層化されたサイズ分布を用いて生成した23,500のクラスターから80,690,777トリプルを導出しました。NVIDIA GeForce RTX 3050 GPU は、角度、比、および距離の許容誤差窓内での照合を見つけるためにこれらのトリプルを並列処理しました。生GPUヒット数(158,784)をトリプルの一意なアイデンティティに基づいて重複除去し、候補は8,915に絞られました。
高度な検証には、P0→P1の縁に沿う長方形内に他の陸地massesが含まれていないことを確認する開水路テストが含まれ、これにより候補は948に減少しました。形状チェックは Polsby-Popper スコア(≥0.5)、Micro Cay Halo 数(1.5km 以内に面積0.05 km²未満の断片が1つ以上)、および Oval 方面比・充填率に基づいてさらにフィルタリングされました。Earth Search API(Sentinel-2)による NDVI チェックでは植生指数が0.6より大きいことを必要とし、候補は66に減少しました。標高チェックでは P0 の平坦性が50m以下、P2 の標高が方位角±50°の弧内において100m~500mであることを確認し、生き残った候補は26に減少しました。
データソースには OpenStreetMap の海岸線、Copernicus DEM GLO-30、Natural Earth の国境、ならびに Element84 Earth Search 経由の Sentinel-2 画像が含まれていました。確認された解決策では、特定の座標位置にあるリゾート「Resort Oan」が、カメラが概ね北西方向を向いていることが特定されました。
この達成は、複雑な地理的位置決定の問題が、商用 API を用いるのではなく、公共の衛星データと生の数学的論理を用いて解決可能であることを証明しています。これは、地形モデル、海岸線、植生指数といった多様なデータセットを組み合わせて効率的に複雑なパズルを解決することの可能性を示し、オープンソースインテリジェンスを通じて地理的主張を検証するスケーラブルな手法の有効性を検証するものであり、異なるデータセットの組み合わせによる解決への強みを実証しています。
本文
グラリクス 004:ジオロケーションと CUDA を用いたランダム環礁画像解析
日付: 2026 年 8 月 16 日 注記: 本記事は人間による分析に基づくものであり、LLM の生成物は使用されていません。
このページでは、Sofia Santos | Gralhix によって作成された課題「gralhix 004」の解説を紹介します。コードと詳細な手順は GitHub でクローンし、ローカル環境で検証できます。
🎯 タスク概要
与えられたリゾート地の島写像から以下の情報を抽出すること:
- a) リゾートの名前
- b) 島の座標
- c) カメラの撮影方向(方位角)
Google Lens を使用するのは面白さのない作業であるため、数式とプログラミングを用いたアプローチを採用しました。
🔍 a] メタデータ確認
まずは画像情報から入手できる情報を確認します。Linux Void システム上で以下のコマンドを実行:
exiftool main.png
抽出された結果:
- ファイル形式: WEBP (ロスレス圧縮)
- MIME タイプ:
image/webp - 画像サイズ: 736 × 515 ピクセル
- EXIF データ: GPS やカメラ情報は含まれておらず、地理的情報の提供はありませんでした。
🏝️ b] フィンガープリント構築
画像から観測された 3 つの陸塊(島)を定義します:
- P0: リゾート環礁そのもの
- P1: 右側の島
- P2: 左前方にある山岳のある島
この画像はドローン撮影であり、正確な高度が不明です。そのため、直感に基づいた鳥瞰図透視モデルを作成しました。 画素座標をクリックして幾何形状を計算する GUI ツール
01_triangle_gui.py を作成し、目視による中心特定の不確かさを考慮して ±20% の許容誤差を設定しています。
🌍 c] 地球規模での探索 (SEARCH)
地球上の既知の陸域データ(OpenStreetMap:
land-polygons-split-4326、882 MB)と照合し、フィルタリングプロセスを開始します。
01] 熱帯緯度によるフィルタリング
写真の環礁は熱帯特徴を示しているため、高コストな計算の前に赤道周辺に限定:
$$ -30^\circ \le \text{latitude} \le 30^\circ $$
- 結果: 141,131 の陸域多角形が候補に残りました。
02] ローカル密度フィルタ
高密度な海岸線やサンゴ礁フィールドを除外するため、5km 以内の近隣島嶼数に制限:
$$ N_{5\text{km}}(p) \le 10 $$
- 結果: 候補は 51,576 に減少。
03] クラスタリング
画像の直感に基づき、20km 以内に少なくとも 3 つの島(合計 3 ポイント)が存在する「クラスタ」のみを対象とします。
tree = cKDTree(f_coords) # 半径:約 20km (地球儀での換算係数 111.0 を除) neigh = tree.query_ball_point(f_coords, CLUSTER_RADIUS_KM / 111.0) clusters = set(tuple(sorted(n)) for n in neigh if len(n) >= 3)
- 結果: 23,500 のクラスタに集約。
04] トリプレット生成
各クラスタ内から三角形(トリプル)を抽出します。大規模なクラスタは膨大な組み合わせを含むため、サイズベースの層別サンプリングを行います:
- 小規模島:1/3
- 大規模島:1/3
- 中間サイズ:1/3
$$ \binom{n}{3} = \frac{n(n-1)(n-2)}{6} $$
総トリプル数: 80,690,777 に達しました。
05] GPU によるマッチング
CUDA スレッドを各トリプルに割り当て、並列処理で幾何学的特徴量を計算します:
- ソートと割当: 面積順に P0(最小=環礁)を選出し、巻き回し方向から P1, P2 を決定。
- 2D クロス積: 符号から島の区別を判断(左折/右折)。
- 特徴量計算: 角度 $\theta_0$ と距離比 $r$ を計算し、フィンガープリントと一致するかチェック。
GPU パフォーマンス (NVIDIA GeForce RTX 3050):
- VRAM 使用: 5169 MB
- 実行時間: 204.1 ms
- 並列処理数: 約 8,070 万トリプル
- マスク通過数: 158,784
06] 重複除外
同一物理的トリプルが重複して検出される可能性を排除:
- 結果: 8,915 の一意なトリプル。
07] オープン長方形テスト (The Open Rectangle)
「P0→P1 の辺」に沿って P2 がいない側の水域を開けた水か確認します(陸域データとの交差チェック)。
- 結果: 948 の候補地に残されました。
🪸 d] サンゴ礁環礁の形状チェック (Coral Cay Shape Check)
P0(リゾート環礁)が典型的なサンゴ礁環礁形状であるか確認します。
1] コンパクト性
円形にどれだけ近いかなどを表す Polsby-Popper スコア:
$$ PP = \frac{4\pi \cdot \text{area}}{\text{perimeter}^2} $$
- 判定: 0.5 より低いギザギザした形状は除外。
- 結果: 213/948 が通過。
2] マクロ・ケイ・ハロチェック (Micro Cay Halo Check)
主要島(P0)の周囲に、単独の陸地ではなく小さな砂州断片が散在する構造を確認:
- 条件: P0 から 1.5km 以内で面積 <0.05 km² の断片が存在すること。
- 結果: 213/948 の候補(重複なし)が通過。
🥚 e] 楕円形状チェック (Oval Shape Check)
P0 の多角形に最小回転長方形を適合させ、比率を確認:
アスペクト比
$$ \text{aspect} = \frac{\text{long side}}{\text{short side}} \in [1.05,\ 2.2] $$
- 判定: 円すぎる(1.0 付近)または過度に細長いものは除外。
充填率
楕円の理論限界 ($\approx 0.785$) の 75% を満たすことを確認:
$$ \text{FILL_RATIO} = \frac{\text{area}{\text{ellipse}}}{\text{area}{\text{box}}} \ge 0.589 $$
- 判定: 新月形やリング状は除外。
- 結果: 137/213 が通過。
🌿 f] NDVI 植生チェック
最新の Sentinel-2 スケーン(地球検索 API)を取得し、ヤシの葉による植生を確認:
$$ \text{NDVI} = \frac{\text{NIR} - \text{Red}}{\text{NIR} + \text{Red}} $$
- 閾値: 0.6 以上(裸地や水面は除外)。
- 結果: 66/137 が通過。
⛰️ g] 標高と山岳チェック (Elevation & Mountain Check)
カメラの方位角に基づき、地形条件を確認:
- P0: 低く平坦($\le 50\text{m}$)。
- P2(前方): 高地を持つ必要がある。
スキャン範囲(半径 2km〜20km)で Copernicus DEM データをサンプリング:
$$ \text{elev}(P_0) \le 50\text{m} $$ $$ 100\text{m} \le \max_{\text{arc}}(\text{elev}) \le 500\text{m} $$
- 結果: 66/213 が標高チェックを通過。
- ※注:生存者は南アジア、オーストラリア、オセアニアに集中し、ブラジル付近のみ例外です。
🏁 h] 最終報告 (Final Report)
残った 66 の候補に対し、国名検索と Google マップ衛星画像へのリンクを付与:
- 最初の 7 つは誤りであることが確認。
- **8 つ目(ミクロネシア共和国)**で正解にたどり着く🥳。
✅ i] 最終解答
a) リゾートの名前: $$ \text{Oan} $$
b) 島の座標: $$ 7^\circ,21',48.4'',\text{N} \quad 151^\circ,45',20.7'',\text{E} $$ または $$ (7.363444^\circ,\ 151.755750^\circ) $$
c) カメラの撮影方向: 方位角計算式: $$ \theta = \text{atan2}\Big(\sin(\Delta\lambda)\cos\phi_1,\ \cos\phi_0\sin\phi_1 - \sin\phi_0\cos\phi_1\cos(\Delta\lambda)\Big) $$
- $P_0 = (7.3633,\ 151.755983)$
- $P_1 = (7.386573,\ 151.739534)$
- 計算結果: $\theta \approx 324.97^\circ$
$$ \therefore \quad \text{**NW (北西)} $$
📄 j] データとライセンス
- 海岸線多角形:
land-polygons-split-4326- © OpenStreetMap | ODbL 1.0
- 標高データ: Copernicus DEM GLO-30 (DLR / Airbus)
- © DLR e.V. / Airbus Defence and Space (EU & ESA コペルニクスプログラム)
- 衛星画像: Copernicus Sentinel-2 via Earth Search
- © Element 84 (AWS Open Data プログラム利用)
- 国境データ: Natural Earth 10m admin-0 (パブリックドメイン)
- 課題元: Sofia Santos | Gralhix (OSINT 演習 #004)