444 Views
December 09, 23
スライド概要
第5回 平滑化、先鋭化
2018/05/17 画像情報処理特論 第5回 平滑化、先鋭化 東京工科大学 助教 加納 徹
授業計画 第1回:ガイダンス、Java開発環境の構築 第2回:GUIアプリケーション開発、画像データの入出力 第3回:前処理(1)(二値化処理、画像の配列化) 第4回:前処理(2)(モルフォロジー演算) 第5回:前処理(3)(平滑化、鮮鋭化) 第6回:画像の特徴抽出・特徴解析 第7回:画像の定量評価(MSE、PSNR、CNR) 第8回:コンピュータ診断支援への展開、まとめ 2
注意事項 ⚫ 前回作った GUI を一部削除します ⚫ プロジェクトを右クリックし、 [コピー] で複製しておくことを おすすめします 3
フィルタ処理
フィルタ処理(Filtering) フィルタ処理・・・ノイズ除去や特徴抽出を行う処理 ⚫ 平滑化フィルタ ⚫ 平均値(加重平均)フィルタ ⚫ ガウシアンフィルタ ⚫ メディアンフィルタ ⚫ 鮮鋭化フィルタ ⚫ ソーベルフィルタ ⚫ ラプラシアンフィルタ ⚫ その他のフィルタ ⚫ バイラテラルフィルタ 5 いっぱいあるけど、一つできればあとは簡単
フィルタ処理(Filtering) フィルタ処理・・・ノイズ除去や特徴抽出を行う処理 * 元画像 6 = オペレータ (フィルタ) ? オペレータは、「カーネル」とも呼ばれる 処理画像
平滑化(Smoothing)
平均化フィルタ 周辺の画素の平均値に置き換えるフィルタ 3×3 8 5×5 1/9 1/9 1/9 1/25 1/25 1/25 1/25 1/25 1/9 1/9 1/9 1/25 1/25 1/25 1/25 1/25 1/9 1/9 1/9 1/25 1/25 1/25 1/25 1/25 1/25 1/25 1/25 1/25 1/25 1/25 1/25 1/25 1/25 1/25 かんた~ん
平均化フィルタ 周辺の画素の平均値に置き換えるフィルタ 9 90 90 90 90 90 90 90 90 90 90 90 90 180 90 90 90 90 90 90 90 90 90 90 90 90 * 1/9 1/9 1/9 1/9 1/9 1/9 1/9 1/9 1/9 画像中心にノイズのようなものがある状況を想定
平均化フィルタ 周辺の画素の平均値に置き換えるフィルタ 90 90 90 90 90 90 90 90 90 90 90 90 180 90 90 90 90 90 90 90 90 90 90 90 90 * 1 1 1 1 9 9 9 9 90 × + 90 × + 90 × +90 × 1/9 1/9 1/9 1/9 1/9 1/9 1/9 1/9 1/9 1 1 9 9 +90 × +90 × = 90 90 90 90 90 90 100 90 90 90 90 90 180 90 90 90 90 90 90 90 90 90 90 90 90 1 1 9 9 +90 × + 𝟏𝟖𝟎 × = 𝟏𝟎𝟎
平均化フィルタ 周辺の画素の平均値に置き換えるフィルタ 11 90 90 90 90 90 90 90 90 90 90 90 90 180 90 90 90 90 90 90 90 90 90 90 90 90 * 1/9 1/9 1/9 1/9 1/9 1/9 1/9 1/9 1/9 = 90 90 90 90 90 90 100 100 100 90 90 100 100 100 90 90 100 100 100 90 90 90 90 90 90 尖った部分が じわぁ~~ っと広がるイメージ
加重平均フィルタ 周辺の画素の重み付き平均値に置き換えるフィルタ 3×3 5×5 1/10 1/10 1/10 1/35 1/35 1/35 1/35 1/35 1/10 2/10 1/10 1/35 2/35 2/35 2/35 1/35 1/10 1/10 1/10 1/35 2/35 3/35 2/25 1/35 1/35 2/35 2/35 2/35 1/35 1/35 12 1/35 1/35 1/35 1/35 中心ほど影響を大きくすることで緩やかな平滑化となる
ガウシアンフィルタ フィルタの重みを正規分布(ガウス分布)にしたフィルタ 3×3 1/16 2/16 1/16 2/16 4/16 2/16 5×5 1/256 4/256 6/256 4/256 1/256 4/256 16/256 24/256 16/256 4/256 1/16 2/16 1/16 6/256 24/256 36/256 24/256 6/256 4/256 16/256 24/256 16/256 4/256 1/256 13 4/256 6/256 4/256 みんな大好き 正規分布 はやっぱり美しいですね 1/256
メディアン(中央値)フィルタ 周辺の画素の中央値に置き換えるフィルタ (ゴマ塩ノイズの除去に適している) 14 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 180 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 * メディアン フィルタ = ノイズがきれいさっぱりなくなった!
フィルタ処理の実装 これからは GUI も自分好みに実装していってみよう 15
フィールドで以下の変数を宣言 final int MAX_WIDTH = 1024, MAX_HEIGHT = 1024; int imageWidth, imageHeight; int[] imageData = new int[MAX_WIDTH * MAX_HEIGHT]; int[] imageDataBinary = new int[MAX_WIDTH * MAX_HEIGHT]; int[] imageDataBinaryBuffer = new int[MAX_WIDTH * MAX_HEIGHT]; int[] imageDataFiltered = new int[MAX_WIDTH * MAX_HEIGHT]; float[] filter = {1/9f, 1/9f, 1/9f, 1/9f, 1/9f, 1/9f, 1/9f, 1/9f, 1/9f}; int black = Color.black.getRGB(); int white = Color.white.getRGB(); … … 16
フィルタ処理の実装
btnFilteringActionPerformed を以下のように変更
private void btnFilteringActionPerformed(java.awt.event.MouseEvent evt) {
if (bufImage == null) return; // 画像パネルが空の場合、終了
int gray;
float newValue;
for (int y = 1; y < imageHeight - 1; y++) {
for (int x = 1; x < imageWidth - 1; x++) {
newValue = 0;
for (int fy = 0; fy < 3; fy++)
for (int fx = 0; fx < 3; fx++)
newValue += imageData[(y - 1 + fy) * imageWidth + x - 1 + fx] * filter[fy * 3 + fx];
gray = (int) newValue;
if (gray > 255) gray = 255;
if (gray < 0) gray = 0;
imageDataFiltered[y * imageWidth + x] = gray;
bufImageShow.setRGB(x, y, new Color(gray, gray, gray).getRGB());
}
}
imageData = Arrays.copyOf(imageDataFiltered, imageData.length);
lblDraw.setIcon(new ImageIcon(bufImageShow));
}
【発展】フィルタ処理のメソッド化
btnFilteringActionPerformed をメソッド化
private void btnFilteringActionPerformed(java.awt.event.MouseEvent evt) {
if (bufImage == null) return; // 画像パネルが空の場合、終了
int gray;
float newValue;
for (int y = 1; y < imageHeight - 1; y++) {
for (int x = 1; x < imageWidth - 1; x++) {
newValue = 0;
for (int fy = 0; fy < 3; fy++)
for (int fx = 0; fx < 3; fx++)
newValue += imageData[(y - 1 + fy) * imageWidth + x - 1 + fx] * filter[fy * 3 + fx];
gray = (int) newValue;
if (gray > 255) gray = 255;
if (gray < 0) gray = 0;
imageDataFiltered[y * imageWidth + x] = gray;
bufImageShow.setRGB(x, y, new Color(gray, gray, gray).getRGB());
}
}
imageData = Arrays.copyOf(imageDataFiltered, imageData.length);
lblDraw.setIcon(new ImageIcon(bufImageShow));
}
【発展】フィルタ処理のメソッド化 btnFilteringActionPerformed をメソッド化 private void btnFilteringActionPerformed(java.awt.event.MouseEvent evt) { if (bufImage == null) return; // 画像パネルが空の場合、終了 // フィルタ処理 setFilter(*****); imageData = Arrays.copyOf(imageDataFiltered, imageData.length); lblDraw.setIcon(new ImageIcon(bufImageShow)); } 「メソッド」は、一連の処理をまとめたものだったね 19 どこからでも何度でも呼び出せてらくちん
メソッドの作り方① int calc(int x) { int res; resメソッドの処理内容 = x * x + 3 * x; (計算や文字の表示等) return res; } 戻り値や引数が無い場合は、void(空っぽの意味)と記入
メソッドの作り方② int calc(int x) { int res; res = x * x + 3 * x; return res; } 引数として受け取った値は x に格納され、関数内で自由に使える
【発展】フィルタ処理のメソッド化
フィールドで setFilter() メソッドを作成
void setFilter(float[] filterType, int filterSize) {
int gray, dif = filterSize / 2;
float newValue;
for (int y = dif; y < imageHeight - dif; y++) {
for (int x = dif; x < imageWidth - dif; x++) {
newValue = 0;
for (int fy = 0; fy < filterSize; fy++)
for (int fx = 0; fx < filterSize; fx++)
newValue += imageData[(y - dif + fy) * imageWidth + x - dif + fx]
* filterType[fy * filterSize + fx];
gray = (int) newValue;
if (gray > 255) gray = 255;
if (gray < 0) gray = 0;
imageDataFiltered[y * imageWidth + x] = gray;
bufImageShow.setRGB(x, y, new Color(gray, gray, gray).getRGB());
}
}
}
22
【発展】フィルタ処理のメソッド化 setFilter メソッドの呼び出し private void btnFilteringActionPerformed(java.awt.event.MouseEvent evt) { if (bufImage == null) return; // 画像パネルが空の場合、終了 // フィルタ処理 setFilter(filter, 3); imageData = Arrays.copyOf(imageDataFiltered, imageData.length); lblDraw.setIcon(new ImageIcon(bufImageShow)); } アー君 おーく君 & おーく子ちゃん あーくちゃん 樫木筆夫 ちくわ君 A-CORN Ping Pig セミコロン; 樫の木君 プログラミング小僧 Mr. O かめおかさん 赤貝ちゃん わんわんおーく 右下でうだうだ言うキャラクタ募集中 (プロフィールを添えて送ってね)
平均化処理の実行結果 元画像 平均化処理 ちょっとだけぼやけた 24
フィルタ選択処理の実装 model: 平均化フィルタ(3×3) 平均化フィルタ(5×5) ・・・・・・ ・・・・・・ 必要に応じて項目を増やしていこう 25
コンボボックスの判定
btnFilteringActionPerformed の中身の例
if (cmbFilter.getSelectedItem().equals("平均化フィルタ(3×3)")) {
//平均化フィルタ(3×3)が選択されているときの処理
setFilter(filterSmooth3, 3);
} else if (cmbFilter.getSelectedItem().equals("平均化フィルタ(5×5)")) {
//平均化フィルタ(5×5)が選択されているときの処理
setFilter(filterSmooth5, 5);
}
・・・
・・・
} else {
// 例外処理
JOptionPane.showMessageDialog(this, "Error!");
}
26
getSelectedIndex() で選択位置による分岐にもできる
演習問題 【演習1】 5 × 5の平均化フィルタを作成し、適用させなさい。 【課題2】 加重平均フィルタ、ガウシアンフィルタ配列を作成し、 処理を適用させなさい。 【発展課題】 メディアンフィルタを作成し、処理を適用させなさい。 メディアン(中央値)を探すには、まずソート(整列)! 27
鮮鋭化(Sharpening)
鮮鋭化フィルタ(アンシャープマスク) 平滑化データを差し引くことで鮮鋭化するフィルタ 4近傍鮮鋭化 29 8近傍鮮鋭化 0 -1 0 -1 -1 -1 -1 5 -1 -1 9 -1 0 -1 0 -1 -1 -1 画像がシャープになってエッヂが強調されるぞ
1次微分フィルタ 隣接するピクセルの差(微分)を可視化するフィルタ 垂直方向 水平方向 30 0 0 0 0 0 0 0 1 -1 0 1 0 0 0 0 0 -1 0 シンプルにエッジを検出することができる
Prewitt フィルタ 平滑化しつつ鮮鋭化するフィルタ 垂直方向 水平方向 31 -1 0 1 -1 -1 -1 -1 0 1 0 0 0 -1 0 1 1 1 1 エッジを取る方向に対して垂直方向にぼかすフィルタ
Sobel フィルタ Prewitt フィルタの中央に重み付けをしたフィルタ 垂直方向 水平方向 32 -1 0 1 -1 -2 -1 -2 0 2 0 0 0 -1 0 1 1 2 1 Prewitt の上位互換なんだなぁ
Laplacian フィルタ 最も一般的な2次微分フィルタ 4近傍 33 8近傍 0 1 0 1 1 1 1 -4 1 1 -8 1 0 1 0 1 1 1 水平方向も垂直方向もまとめてエッジ検出ができる!
演習問題 【演習1】 アンシャープマスクを作成し、適用させなさい。 【課題2】 Sobel フィルタおよび Laplacian フィルタを作成し、 処理を適用させなさい。 【発展課題】 5×5 の鮮鋭化オペレータを作成し、フィルタ処理を 適用させなさい。 オペレータの法則を見つけよう 34
その他のフィルタ
Bilateral フィルタ エッジを保存しつつ平滑化するフィルタ σ𝑙 σ𝑘 𝐼 𝑘, 𝑙 exp − 𝐼𝑓 𝑖, 𝑗 = σ𝑙 σ𝑘 exp − 𝑖−𝑘 𝑖−𝑘 2 2 + 𝑗−𝑙 2𝜎𝑑2 + 𝑗−𝑙 2𝜎𝑑2 2 2 − − ||𝐼 𝑖, 𝑗 − 𝐼 𝑘, 𝑙 || 2𝜎𝑟2 ||𝐼 𝑖, 𝑗 − 𝐼 𝑘, 𝑙 || 2𝜎𝑟2 𝐼𝑓 : フィルタ処理後の画像 𝐼 : 入力画像 𝜎𝑑 : 平滑化係数(ガウシアンフィルタの係数と等価) 𝜎𝑟 : 平滑化係数(注目画素と周辺画素の許容輝度差) 36 パラメータの調整に骨が折れそう・・・
宿題 以下の課題を Word 等で作成し、PDF形式で提出しなさい。 (ファイル名:学籍番号_氏名.pdf) 【課題1】 平滑化フィルタと鮮鋭化フィルタを組み合わせ、ノイズを抑えつ つ鮮鋭な画像を作成しなさい。 【課題2】 モルフォロジー演算の前にフィルタ処理を行うことで、前回課題 の結果とどのような違いが生じるか、考察しなさい。 【発展課題】 メディアンフィルタ、バイラテラルフィルタなど、さまざまな フィルタを実装しなさい。 (メディアンフィルタのヒント: Arrays.sort() メソッド) ※適宜スクリーンショットや処理画像を掲載すること 37
お疲れ様でした つづく