キー | 画像 | 意味 | 特徴 |
---|---|---|---|
0 | ノイズ.jpg | 元画像を実行画面の半分の大きさにリサイズし、ノイズを加えた画像 | ランダムな色の1000個のノイズがある |
1 | 1移動平均1.jpg | 移動平均フィルタ (半径1) で「ノイズ.jpg」を平滑化した画像 | 全体にぼやけ、ノイズが薄まる |
2 | 1移動平均2.jpg | 移動平均フィルタ (半径4) で「ノイズ.jpg」を平滑化した画像 | 1キーの画像よりさらにぼやけ、ノイズが薄まる |
3 | 2_1ガウシアン4広.jpg | ガウシアンフィルタ (半径4, \(\sigma=2\sqrt{2\log_e 2}\)) で「ノイズ.jpg」を平滑化した画像 | 2キーの画像よりぼやけ方は少ない |
4 | 2_2ガウシアン4狭.jpg | ガウシアンフィルタ (半径4, \(\sigma=\sqrt{2\log_e 2}\)) で「ノイズ.jpg」を平滑化した画像 | 3キーの画像よりぼやけ方は少ないが、ノイズが目立つ |
5 | 3メディアン1.jpg | メディアンフィルタ (半径1) で「ノイズ.jpg」を平滑化した画像 | ほぼ完全にノイズが消える |
6 | 3メディアン2.jpg | メディアンフィルタ (半径2) で「ノイズ.jpg」を平滑化した画像 | ほぼ完全にノイズが消える 細かい形状がつぶれてパステル調になる |
ArrayList<Integer> r = new ArrayList<Integer>();
r.add(3); r.add(5);
r.stream().mapToInt(Integer::intValue).summaryStatistics().getAverage();
import java.util.ArrayList; import java.util.IntSummaryStatistics; import java.util.Collections; // 画像用の変数 PImage[] img = new PImage[7]; // 出力ファイル名 String[] fName = {"ノイズ", "1移動平均1", "1移動平均4", "2_1ガウシアン4広", "2_2ガウシアン4狭", "3メディアン1", "3メディアン2"}; int w, h; void setup() { size(800, 600); w = width/2; h = height/2; img[0] = loadImage("元.jpg"); img[0].resize(w, h); for (int i=0; i<1000; i++) { int x=(int)(random(w)); int y=(int)(random(h)); img[0].pixels[x+w*y] = color(random(256), random(256), random(256)); } // 1~6番をノイズ画像と同じ画像にする for (int i=1; i<=6; i++) { img[i] = img[0].get(); } textFont(createFont("MS Pゴシック", 48)); simpleMovingAverage(1, 1);// 移動平均フィルタ(半径1)でぼかした画像をimg[1]に保存 simpleMovingAverage(4, 2);// 移動平均フィルタ(半径4)でぼかした画像をimg[2]に保存 double s = Math.sqrt(2*Math.log(2)); // 隣の画素の重みが中心の画素1/2になるσの値 gaussian(4, s*2, 3); // ガウシアンフィルタ(半径4, σが2s)でぼかした画像をimg[3]に保存 gaussian(4, s, 4); // ガウシアンフィルタ(半径4, σがs)でぼかした画像をimg[4]に保存 median(1, 5); // メディアンフィルタ(半径1)でぼかした画像をimg[5]に保存 median(2, 6); // メディアンフィルタ(半径2)でぼかした画像をimg[6]に保存 println("完了"); image(img[0], 0, 0, width, height); img[0].save("data/"+ fName[0] +".jpg"); } void draw() { } // 移動平均フィルタでぼかす(課題1) void simpleMovingAverage(int radius, int n) { for (int j=0; j<h; j++) { for (int i=0; i<w; i++) { ArrayList<Integer> r = new ArrayList<Integer>(); ArrayList<Integer> g = new ArrayList<Integer>(); ArrayList<Integer> b = new ArrayList<Integer>(); // i±radius, j±radiusの範囲の平均色を求める for (int y=-radius; y<=radius; y++) { for (int x=-radius; x<=radius; x++) { if (i+x>=0 && i+x<w && j+y>=0 && j+y<h) { color c = img[0].pixels[i+x+(j+y)*w]; // (i, j)から(x, y)ずれた位置の色 // rにcの赤成分を追加する // gにcの緑成分を追加する // bにcの青成分を追加する } } } // ar, ag, abにr, g, bの平均値をfloat化して入れる float ar = 0; float ag = 0; float ab = 0; img[n].pixels[i+j*w] = color(ar, ag, ab); } } img[n].save("data/"+ fName[n] +".jpg"); } // ガウシアンフィルタでぼかす(課題2) void gaussian(int radius, double sigma, int n) { } // メディアンフィルタでぼかす(課題3) void median(int radius, int n) { } void keyPressed() { int k = key-'0'; if (k>=0 && k<=6) { background(0); image(img[k], 0, 0, width, height); fill(255, 0, 0); text(fName[k], 30, height-30); fill(255); } }
r.add(int(red(c)));
float ar = 0; float ag = 0; float ab = 0;
float ar = (float)r.stream().mapToInt(Integer::intValue).summaryStatistics().getAverage(); float ag = (float)g.stream().mapToInt(Integer::intValue).summaryStatistics().getAverage(); float ab = (float)b.stream().mapToInt(Integer::intValue).summaryStatistics().getAverage();
1 | 2 | 1 |
2 | 4 | 2 |
1 | 2 | 1 |
1 | 4 | 6 | 4 | 1 |
4 | 16 | 24 | 16 | 4 |
6 | 24 | 36 | 24 | 6 |
4 | 16 | 24 | 16 | 4 |
1 | 4 | 6 | 4 | 1 |
ArrayList<Integer> r = new ArrayList<Integer>(); ArrayList<Integer> g = new ArrayList<Integer>(); ArrayList<Integer> b = new ArrayList<Integer>();
float ar = 0; // 赤成分の平均値 float ag = 0; // 緑成分の平均値 float ab = 0; // 青成分の平均値 double sum = 0; // 重み係数の総和
// i±radius, j±radiusの範囲の平均色を求める
// i±radius, j±radiusの範囲の、重みをつけた平均色を求める
color c = img[0].pixels[i+x+(j+y)*w]; // (i, j)から(x, y)ずれた位置の色
double gauss = Math.exp(-(x*x+y*y)/2/sigma/sigma); // (i, j)から(x, y)ずれた位置での重み係数
r.add(int(red(c)));// rにcの赤成分を追加する g.add(int(green(c)));// gにcの緑成分を追加する b.add(int(blue(c)));// bにcの青成分を追加する
ar += red(c) * gauss;// cの赤成分に重み係数をかけた値をarに加える ag += green(c) * gauss;// cの緑成分に重み係数をかけた値をagに加える ab += blue(c) * gauss;// cの青成分に重み係数をかけた値をabに加える sum += gauss;
// ar, ag, abにr, g, bの平均値をfloat化して入れる float ar = (float)r.stream().mapToInt(Integer::intValue).summaryStatistics().getAverage(); float ag = (float)g.stream().mapToInt(Integer::intValue).summaryStatistics().getAverage(); float ab = (float)b.stream().mapToInt(Integer::intValue).summaryStatistics().getAverage();
// ar, ag, abを重み係数の総和で割る ar /= sum; ag /= sum; ab /= sum;
Collections.sort(r);
// i±radius, j±radiusの範囲の平均色を求める
// i±radius, j±radiusの範囲の中央番目の色を求める
// ar, ag, abにr, g, bの平均値をfloat化して入れる float ar = (float)r.stream().mapToInt(Integer::intValue).summaryStatistics().getAverage(); float ag = (float)g.stream().mapToInt(Integer::intValue).summaryStatistics().getAverage(); float ab = (float)b.stream().mapToInt(Integer::intValue).summaryStatistics().getAverage(); img[n].pixels[i+j*w] = color(ar, ag, ab);
// r, g, bそれぞれの要素を小さい順に並べ替える Collections.sort(r); Collections.sort(g); Collections.sort(b); // それぞれの色成分の中央番目の色を(i, j)のピクセルに設定する img[n].pixels[i+j*w] = color(r.get(r.size()/2), g.get(g.size()/2), b.get(b.size()/2));