建物ヒートマップ表示を、AIによる建物マスクへ切り替えた話
発電量予測機能を実装する中で、かなり長い間苦しめられた問題がありました。
それが、
「ヒートマップが建物からズレて表示される」
という問題です。
エラーが出るわけではありません。
むしろ、一見すると「それっぽく」表示されます。
ただ、よく見るとズレている。
しかも建物によってズレ方が違う。
この問題を解決するために、最終的には AI 部署のエンジニアに協力してもらい、
- 航空画像から
- 中心建物を検出し
- 建物だけをマスクする
という API を作ってもらうところまで進みました。
今回は、その実装に至るまでの話です。
以前の実装で発生した問題
以前の実装では、
- maskUrl
- boundingBox
を利用して、対象建物の領域だけを表示するようにしていました。
しかし、実際にはかなり問題がありました。
boundingBox は上下が水平で左右が垂直な四角形なので、不要な領域が含まれてしまう
boundingBox は上下が水平で左右が垂直が四角形です。
そのため、建物が密集している場所では、どうしても不要な領域が含まれてしまいます。
例えば、対象建物を囲むboundingBox内に、隣の建物の屋根が入り込むケースです。
イメージ 赤いboundingBox内に他の建物が含まれる
- 本来対象ではない黄色部分にもヒートマップが表示される
という問題が発生していました。
特に住宅街ではかなり目立ちました。
さらに厄介だった「ズレ」の問題
もっと苦しかったのは、表示位置のズレです。
しかも、この問題がかなり厄介でした。
なぜなら、
- エラーは出ない
- 座標も間違っていないように見える
- 一部の建物では正常に見える
からです。
つまり、
「何が原因なのか分からない」
という状態でした。
Google Maps の視点
かなり長い時間、何度も表示を繰り返して気づいたのが、
Google Maps の航空画像は、完全な真上視点ではない
ということでした。
例えば、建物によっては屋根だけではなく、側面が少し映っています。
つまり、航空画像の写り方にパースが入っている。
これによって、
- 実際の座標
- 画像上の建物位置
が微妙にズレていました。
実際は↓のように屋根に重ねて表示されて欲しいが、
しかも厄介なのが、
- 建物によって写り方が違う
- 場所によってズレ方が違う
- 真上に近い建物もある
という点です。
なので、
固定値で位置補正する
みたいな逃げ方ができませんでした。
この時はかなり絶望感がありました。
AIチームと一緒に解決方法を探した
当時、発電量予測自体を AI チームと進めていたこともあり、
「ヒートマップ表示側も AI で解決できないか?」
という話になりました。
こちらとしては、
「画像から、中心の建物だけ取れないか?」
という要件を伝えました。
ただ、この時難しかったのが、自分はAIのエンジニアでないため
- どの程度の精度が出るのか
- どのくらいの速度なのか
- 学習データがどんなものなのか
が分からなかったことです。
AI 系の実装は、
できる/できない
が最初から明確に分からない。
なので、
- 要件の伝え方
- 期待値の共有
- 実現可能性
のすり合わせがかなり難しかったです。
AIで「中心建物だけをマスク」するAPIを作ってもらった
最終的には、
- 上空画像を送信
- 画像中央の建物を検出
- 建物だけをマスクした画像を返す
という API を作ってもらいました。
この時点でかなり希望が見えました。
今までは、
- 外部データ
- boundingBox
- maskUrl
の制約の中で戦っていました。
でも今回は、
「自分たちが必要な形でマスクを返せる」
ようになったからです。
「建物だけ返す」と逆にズレる問題
ただ、ここでもハマりポイントがありました。
最初は、
中心建物だけ切り抜いた画像
を返してもらうことを考えていました。
しかし、これだとまたズレます。
理由は単純で、
- クリック位置が少しズレる
- 建物中心がズレる
- 切り抜き位置が変わる
からです。
つまり、
「建物だけ切り抜く」と、座標系が壊れる
という問題がありました。
これは、今まで散々ズレ問題を見ていたので、相談時点である程度予想していました。
元画像サイズのまま返すことで解決した
最終的には、
- 元の航空画像サイズを維持
- その中で中心建物だけをマスク
- マスク部分を赤塗り
- そのままオーバーレイ
という形にしました。
これによって、
- 座標系を維持したまま
- 建物だけを正確に表示
できるようになりました。
完璧ではない。でも大きく前進した
もちろん、完璧ではありません。
例えば、
- 建物が密集している
- 影で境界が見えづらい
場合などは、AI の精度に依存する部分があります。
ただ、
「位置がズレる」
という長年の課題はかなり改善されました。
特に、
- 自社実装として改善できる
- 調整できる余地がある
- 問題解決の方向性が見えた
という点が大きかったです。
今まで「どうにもならない」と感じていた問題に対して、
ようやく突破口が見えた瞬間でした。
まとめ
今回の実装では、
- boundingBox
- 航空画像
- オーバーレイ
- 建物マスク
など、かなり多くの要素が絡んでいました。
特に難しかったのは、
「座標は合っているのに、見た目がズレる」
という問題です。
しかも原因は、
- APIでもなく
- コードでもなく
- 航空画像そのものの写り方
にありました。
最終的には、
- AI による建物検出
- 元画像サイズ維持
- 建物単位マスク
という形で解決へ近づけることができました。
この実装は、
単純な地図オーバーレイではなく、
「画像・座標・見た目」をどう一致させるか
との戦いだったと思っています。