Algorithm & UI/UX
輝度を熱分布に変換する「疑似カラーマッピング」の技術的背景
本ツールは、実際の熱センサーを使用する代わりに、画像の「明るさ(輝度)」を温度に見立て、独自のカラーパレットへ再マッピングすることでサーモカメラのような視覚効果を得ています。ここでは、その計算ロジックと描画パフォーマンスの最適化について解説します。
このツールの入力から出力まで
現行コードの確認日:
- 入力
- 写真を選び、色の強さなどを調整します。
- 処理
- 各画素の明るさを疑似的なカラーマップへ対応させ、サーモグラフィ風の色に置き換えます。
- 出力
- 長辺最大 1500px、JPEG(品質指定 0.9)で保存します。
まず確認する点:元画像の明るさを色にしているため、温度ではありません。暗い物が冷たい、明るい物が熱いという測定結果にはできません。
仕上がりの例
写真をサーモグラフィ風の色に変えた例です。
掲載画像はサイトにある既存の公開作例です。保存済みの資料では運営者の愛猫の写真を使用しています。今回の確認日が、この作例を実行した日を表すわけではありません。
保存済み検証記録の条件を見る
資料の種類は「ツールの出力画像を保存した記録」です。公開作例と保存済み記録で素材や色などが異なる場合があるため、下の数値は保存済み検証記録の条件として読んでください。
- 記録の入力画像
- 800×1066px (JPEG)
- 記録の出力画像
- 800×1066px (JPEG)
| 画面の項目 | 記録の値 | 現行コードの初期値・範囲 |
|---|---|---|
| 記録で選択されていた項目 | 通常 (熱=赤) | — |
| 全体の色合い (温度感) | 0 | 初期値 0 / 範囲 -50〜50 |
| 熱のコントラスト | 120 | 初期値 120 / 範囲 50〜200 |
記録では「画像を保存するへ進む」から完成表示へ進んでいます。初期値と記録値を比べてから、効果を1項目ずつ変えると作用を確認しやすくなります。
資料ファイルの作成日は実行日として扱っていません。個別端末の処理速度や、ほかの写真に対する検出・加工の精度を測定した資料でもありません。
実装の確認箇所:src/pages/image/thermal/index.astro。以下のコード抜粋と出力条件は、この本番実装に基づいて説明します。
仕組みを読み進めるときは、Canvas APIと画像処理(画像寸法、drawImage、画素と透明度の扱い)、メモリ管理と画像処理(画素バッファ、縮小と容量予算)が参考になります。
1. 輝度ベースの疑似カラー変換とコントラスト調整
サーモグラフィ特有の「熱い部分は赤く、冷たい部分は青い」という表現は、画像処理における「疑似カラー変換」の一種です。まず各ピクセルのRGB値を人間が感じる明るさ(輝度)へ変換し、それを温度のインデックスとして扱います。
この際、単純なグレースケール変換だけでなく、スライダーによる「コントラスト(熱の強弱)」と「オフセット(全体的な温度感)」の補正を数式に組み込んでいます。これにより、暗い写真でも色の分布を変える調整が可能になります。
RGB の明るさをパレット番号へ変換する例です。temp は −50〜50、contrast は 50〜200 で、温度の単位ではありません。
function thermalIndex(r, g, b, temp = 0, contrast = 120, invert = false) {
let y = r * 0.299 + g * 0.587 + b * 0.114;
y = ((y / 255 - 0.5) * contrast / 100 + 0.5) * 255;
y += temp / 100 * 255;
if (invert) y = 255 - y;
return Math.max(0, Math.min(255, Math.floor(y)));
} 2. 256色の動的サーモパレット生成(Jet風グラデーション)
静的な画像ファイルとしてパレットを持つ代わりに、実行時に256色のRGB配列をプログラムで生成しています。この手法のメリットは、リソースの軽量化だけでなく、パレットの境界値を微調整することで「より熱そうに見える配色」を柔軟に定義できる点にあります。
計算は 濃青 -> 青 -> シアン -> 緑 -> 黄 -> 赤 -> 白 の順に色が遷移するように、特定の閾値ごとにRGB各チャンネルを線形補間しています。
3. Canvas 2D APIによる高速ピクセル処理のハック
高解像度の画像をリアルタイムで加工するため、Canvasの ImageData を直接操作しています。数百万ピクセルに及ぶループ処理をブラウザのメインスレッドで完結させるため、いくつかの最適化を施しています。
一つは willReadFrequently: true フラグの使用です。これはブラウザに対し、頻繁にピクセルデータの読み取りが発生することを伝え、メモリ配置を最適化させるためのものです。また、リサイズ処理を前段に挟むことで、処理対象のデータ量を一定以下に抑え、処理する画素数を減らしています。描画処理はメインスレッド上で動き、応答速度は端末によって異なります。
出力の仕様と確認する点
これは写真の明るさに色を割り当てる画像加工です。赤外線の取得、物体の温度測定、発熱や断熱性能の判断はできません。白い物体が赤くなっても高温という意味ではありません。
温度感はパレット番号を全体に加減し、コントラストは中間の明るさからの差を広げます。反転モードでは番号を 255 から引くため、明暗と色の対応が逆になります。
長辺最大 1500px、JPEG(品質指定 0.9)で保存します。しきい値外は 0 または 255 に丸めるため、強い設定では異なる明るさが同じ色になる場合があります。
