Canvasで空間フィルタを実装する―平滑化とエッジ検出【画像処理100本ノック】
約 4 分
目次
概要
Gasyori100knockJSのQ.9〜19では、 近傍画素を使った平滑化とエッジ検出を実装しています。
畳み込みの基本
空間フィルタは、注目画素の周囲にカーネルを重ね、画素値と係数の積和を出力します。 3×3カーネルなら、画像の各座標で9画素を参照します。
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
for (let ky = -1; ky <= 1; ky++) {
for (let kx = -1; kx <= 1; kx++) {
const sx = Math.min(width - 1, Math.max(0, x + kx));
const sy = Math.min(height - 1, Math.max(0, y + ky));
value += src.data[(sy * width + sx) * 4 + channel] *
kernel[ky + 1][kx + 1];
}
}
}
}
端の画素では画像外を参照しないように座標をクランプします。RGBを個別に計算し、アルファ値は 255のままにするのが各実装に共通する流れです。
平滑化フィルタ(Q.9〜12)
| 問題 | 実装の要点 |
|---|---|
| Q.9 ガウシアン | 距離に応じたガウス分布の重みを3×3へ配置し、カーネルの合計が1になるよう正規化する |
| Q.10 メディアン | 3×3近傍の9個の値を並べ替え、中央の値を選ぶ |
| Q.11 平滑化 | 3×3の全係数を1 / 9にした平均フィルタを畳み込む |
| Q.12 モーション | 左上から右下の対角成分だけに1 / 3を置き、一定方向のぶれを作る |
ガウシアンフィルタと平均フィルタはいずれもローパスフィルタですが、ガウシアンは中心に近い 画素ほど重くするため、単純平均より自然にぼかせます。メディアンフィルタは積和を使わず、 外れ値の影響を受けにくいのでごま塩ノイズに向いています。
エッジ検出フィルタ(Q.13〜19)
| 問題 | カーネルまたは処理 | 特徴 |
|---|---|---|
| Q.13 MAX-MIN | 近傍の最大値−最小値 | 局所的な濃度差を直接取り出す |
| Q.14 微分 | 隣接画素の差 | 水平・垂直方向の輪郭を分けて確認できる |
| Q.15 Sobel | 中央の行・列を強くした一次微分 | 微分と平滑化を同時に行う |
| Q.16 Prewitt | 行・列を均等に重み付けした一次微分 | Sobelより単純な係数で勾配を求める |
| Q.17 Laplacian | 二次微分 | 方向に依存しないエッジを得る |
| Q.18 Emboss | 対角方向の差+128 | 明暗差を浮き彫りとして見せる |
| Q.19 LoG | ガウシアン+Laplacian | ノイズを抑えてから二次微分する |
一次微分フィルタはx方向とy方向を別々に適用します。横方向の輝度変化を計算すると縦線が、 縦方向の変化を計算すると横線が強く出ます。
Laplacianは二次微分なので方向を分けませんが、ノイズも強調します。LoGでは先にガウシアンで 平滑化することで、この弱点を補っています。
実装を読むときのポイント
同じ「輪郭を抽出する」処理でも、カーネルによって方向性、ノイズへの強さ、線の太さが変わります。 デモでは同じ入力画像に各フィルタを適用し、出力の違いを比較できます。
畳み込みの実装を追うときは、次の順で確認すると理解しやすくなります。
- カーネルの係数と合計
- 画像端で使う座標
- RGBをそのまま処理するか、グレースケールへ変換するか
- 負の計算結果をどのように0〜255へ収めるか
関連記事
おすすめの記事
最新の記事
よく読まれている記事
タグから探す
- javascript129
- typescript66
- node.js54
- linux54
- 画像処理48
- amazon-aws47
- アルゴリズム37
- canvas35
- html529
- 画像処理100本ノック27
- php24
- centos24
- python22
- 競技プログラミング21
- mac21
- mysql20
- opencv17
- 雑談16
- 機械学習16
- docker16
- wordpress15
- atcoder14
- apache12
- データベース12
- amazon-s312
- red-hat12
- prisma12
- ubuntu11
- github10
- git10
- react10
- mariadb10
- vue.js9
- aws-cdk9
- css38
- 可視化8
- 小ネタ8
- next.js8
- nestjs8
- amazon-lightsail7
- ブログ6
- cms6
- oracle6
- perl6
- gitlab6
- iam5
- amazon-ec25
- 資格試験5
- aws-amplify5
- curl4