フィルタは周りのピクセルと混ぜる
ぼかしフィルタとは、各ピクセルを、まわりのピクセルと混ぜて、ざらつきを減らす処理です。ノイズの多い画像も、フィルタを通すと、読みやすくなります。
たとえば、古いコピー機で取り込んだ書類には、白と黒の点がたくさん付きます。その点を目立たなくするのが、フィルタの仕事です。
このレッスンのゴール
メモ
3×3 のカーネルを使って、画像のざらつきをフィルタで減らせる。
キーワード
| ことば | いみ | れい |
|---|---|---|
| ノイズ | 画像に混ざる、関係のないざらつき | |
| カーネル | 重みを並べた小さな表。ふつうは 3×3 | 3×3 |
| フィルタ | 周りのピクセルを使って、各ピクセルを直す処理 | |
| 平均ぼかし | 範囲の値を平均して、ぼかす方法 | |
| 中央値 | 小さい順に並べたときの、真ん中の値 | |
| 畳み込み | カーネルをずらして、かけ算して足す計算 |
学生が入力するセルは、このプレビューでは空白です。
カーネルをずらして、かけ算して足す
カーネルは、重みを並べた小さな表です。これを画像の上でずらし、各位置で、重なった値と重みをかけて、全部を足します。
3×3 のカーネルは、画像の端からはみ出せません。結果は、高さも幅も2つずつ小さくなります。
例: 全部が1のカーネルで合計する
| 範囲の中身 | 計算 | 合計 | 9 で割る |
|---|---|---|---|
| 255 が1つ、10 が8つ | 255 + 10 × 8 | 335 | 37 |
| 10 だけ9つ | 10 × 9 | 90 | 10 |
学生が入力するセルは、このプレビューでは空白です。
範囲の合計と、平均を求める
docker exec jupyter python3 -c "print(8 * 10 + 255, (8 * 10 + 255) // 9)"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
中央値は外れた値を消す
平均ぼかしは、255 のような外れた値を、まわりに広げてしまいます。中央値フィルタは、範囲の9つの値を小さい順に並べ、真ん中の5番目を取ります。
255 が1つだけなら、5番目は 10 です。外れた値は消えます。
同じ範囲を、平均と中央値で直す
| 方法 | 範囲 (255 が1つ、10 が8つ) | 結果 |
|---|---|---|
| 平均ぼかし | 合計 335 を 9 で割る | 37 |
| 中央値フィルタ | 並べて5番目を取る | 10 |
学生が入力するセルは、このプレビューでは空白です。
ラボで書類の画像をぼかす
ラボの scan.png は、ざらつきのある書類の画像です。次のスクリプトは、ぼかしを当て、何も書かれていない一角の散らばりを、前と後で表示します。
出力は英語です。spread は散らばり、empty patch は何も書かれていない一角、before は前、after は後の意味です。
ぼかしの前と後を比べる
docker exec jupyter python3 steps/blur.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
散らばりが小さくなった
散らばりは、前が 25.3、後が 4.9 です。ぼかしで、ざらつきは約5分の1になりました。
スクリプトは scan_blurred.png も保存します。JupyterLab で開くと、文字も少し柔らかく見えます。
カーネルを当てる計算
small = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
kernel = [[1, 1, 1], [1, 1, 1], [1, 1, 1]]
result = []
for row in range(len(small) - 2):
result_row = []
for column in range(len(small[0]) - 2):
total = 0
for i in range(3):
for j in range(3):
total = total + small[row + i][column + j] * kernel[i][j]
result_row.append(total)
result.append(result_row)
print(result)
# kernel の真ん中を 1、ほかを 0 に変えて、もう一度実行します。
# 結果は、どうなりますか。
よくある間違い
注意
ぼかせば、ノイズは消えると考えがちです。平均ぼかしは、外れた値を周りに広げて薄めるだけです。点を消したいときは、中央値フィルタを使います。