「小さなフィルタのサンプル5」の編集履歴(バックアップ)一覧はこちら

小さなフィルタのサンプル5」(2010/06/15 (火) 15:26:49) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

*主に2010/6/11から記述開始 作りかけの失敗作フィルタ。 考え付いたものの処理結果がうまくいくかどうかは分からない状態なので、色々パラメータを弄って実験がすんでから、全部のコードを公開予定。 2枚の絵を使うフィルタ。 一枚の絵は教師データで微分される。 もう一枚が教師データを下にフィルタされる絵。 フィルタされるイラストを一回微分して、微分したデータを教師データと比較し教師データに近づけ、最後に積分して元に戻す処理を実行する予定。 うまくいくかどうかはわからないフィルタ。 複雑なフィルタは、うまくいかない場合が多いので望み薄で実装中。 *2010/6/15追記 たいていのイラストや写真では近傍点との色の差分はたいてい小さく、計算式に取り入れることが困難だという単純な事実に気づいた。 汎用性がないのでこのフィルタは破棄。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication4 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { pictFilter2 PF = new pictFilter2(100d, pictureBox1); Bitmap b2 = new Bitmap(pictureBox1.Image); PF.Add_Color_frequency_table(b2); } } public class pictFilter2 { cell_date[, ,] Cells; PictureBox outPictureBox; double cell_size; Bitmap b2;//このデータにフィルタが施される Bitmap outBit; Random rnd=new Random() ; public pictFilter2(double cell_size1,PictureBox p1) { int areaCount=(int)Math.Floor(510 / cell_size1) + 3; outPictureBox = p1; Cells = new cell_date[areaCount, areaCount, areaCount]; for (int i = 0; i < areaCount; i++) { for (int j = 0; j < areaCount; j++) { for (int k = 0; k < areaCount; k++) { Cells[i, j, k] = new cell_date(); } } } this.cell_size = cell_size1; } public void Add_Color_frequency_table(Bitmap b1) { Color CD, CR, CC;//CCが今の升目で後は下、右 for (int i = 0; i < b1.Width-1; i++) { for (int j = 0; j < b1.Height-1; j++) { //イラストフィルタなので数学的厳密さは求めずに適当にデータを取ってます CC = b1.GetPixel(i, j); CD = b1.GetPixel(i, j + 1); CR = b1.GetPixel(i + 1, j); addCellDate(CC, CD); addCellDate(CC, CR); } } } public void set_Pict(Bitmap inBit) { //フィルタをかけるイラストをセットするだけの処理 b2 = inBit; outBit.Dispose(); } public void get_sandMax() { //差分フィルタ } public void addCellDate(Color C1, Color C2) { int r,g,b; r = C1.R - C2.R; g = C1.G - C2.G; b = C1.B - C2.B; this.Cells[getCell_Point(r) ,getCell_Point(g),getCell_Point(b)].add(r,g,b); } public int getCell_Point(int rgb) { return (int)Math.Floor((rgb + 255) /this.cell_size ) + 1; } public cell_date getMaxCountCell(sabunRGB sabun) { List<cell_date> cell_list = new List<cell_date>(); // int maxCount = 1; cell_date cell; //Countのうち最も大きい差分を返す処理 for (int i = -1; i < 1; i++) { for (int j = -1; j < 1; j++) { for (int k = -1; k < 1; k++) { cell = Cells[sabun.Rpoint + i, sabun.Gpoint + j, sabun.Bpoint + k]; if (maxCount < cell.getCount()) { cell_list.Clear(); cell_list.Add(cell); maxCount = cell.getCount(); }else if(maxCount==cell.getCount()){ cell_list.Add(cell); } } } } if (cell_list.Count > 0) { return (cell_list.ElementAt(rnd.Next(cell_list.Count ))); } else { return (new cell_date()); } } public sabunRGB getCellPoint2(Color C1, Color C2) { //近傍点のどれかのピクセルとの差分を計算するためのBean(Java用語) sabunRGB rgb= new sabunRGB(); rgb.sabunR =C1.R-C2.R; rgb.sabunG =C1.G-C2.G; rgb.sabunB =C1.B-C2.B; rgb.Rpoint = getCell_Point((int)(rgb.sabunR)); rgb.Gpoint = getCell_Point((int)(rgb.sabunG)); rgb.Bpoint = getCell_Point((int)(rgb.sabunB)); return rgb; } public void sand_moveFilter1() { //差分空間の近傍から一番頻度の大きい差分を選ぶ処理 Color CD, CR, CC; int [,]nextBit=new int[this.b2.Width,this.b2.Height*3];//計算の中間段階を保持するためのint for (int i = 0; i < this.b2.Width; i++) { for (int j = 0; j < this.b2.Height * 3; j++) { nextBit[i, j] = 0; } } //List<cell_date> cell_list = new List<cell_date>(); // sabunRGB sabun =new sabunRGB() ; cell_date getCell; sabunRGB aveSabun; for (int i = 0; i < b2.Width-1; i++) { for (int j = 0; j < b2.Height-1; j++) { // CC = b2.GetPixel(i, j); CD = b2.GetPixel(i, j + 1); CR = b2.GetPixel(i + 1, j); sabun=getCellPoint2(CC, CD); getCell =getMaxCountCell(sabun); aveSabun=getCell.aveSabunColor(); //フィルタ後結果を計算するため nextBitに計算結果を足していく処理 nextBit[i, j * 3 + 0] += 0.125*(aveSabun.sabunR * 0.8 + sabun.sabunR*0.2+CC.R+CD.R);   } } } public void sand_miveFilter2() { //差分空間の近傍から最頻値を平均的な確率で差分を修正する処理 } public void sand_miveFilter3() { //差分空間の近傍から最頻値を取り更に上下左右のマスとの平均を足す } public void sand_miveFilter4() { //砂山遊びにヒントを得た処理 2枚の絵の差分を移動して近づける処理 //言うは安し具体的な操作に落とすは難しい } } public class sabunRGB { public int sabunR;//移動前の位置と移動後の位置両方に使う public int sabunG; public int sabunB; public int Rpoint, Gpoint, Bpoint; public int x, y;//差分移動前の元データのピクセル座標、砂遊びフィルタ=sand_miveFilter4で使う } public class cell_date { int sumR =0; int sumG =0; int sumB =0; int count=0; public int getCount() { return count; } public void add(int r, int g, int b) { count++; sumR += r; sumG += g; sumB += b; } public void add(Color C){ count++; sumR += C.R; sumG += C.G; sumB += C.B; } public sabunRGB aveSabunColor() { if (count > 0) { sabunRGB sabun = new sabunRGB(); sabun.sabunR = sumR / count; sabun.sabunG = sumG / count; sabun.sabunB = sumB / count; return sabun; }else{ return (new sabunRGB()); } } } }
*主に2010/6/11から記述開始 作りかけの失敗作フィルタ。 考え付いたものの処理結果がうまくいくかどうかは分からない状態なので、色々パラメータを弄って実験がすんでから、全部のコードを公開予定。 2枚の絵を使うフィルタ。 一枚の絵は教師データで微分される。 もう一枚が教師データを下にフィルタされる絵。 フィルタされるイラストを一回微分して、微分したデータを教師データと比較し教師データに近づけ、最後に積分して元に戻す処理を実行する予定。 うまくいくかどうかはわからないフィルタ。 複雑なフィルタは、うまくいかない場合が多いので望み薄で実装中。 *2010/6/15追記 たいていのイラストや写真では近傍点との色の差分はたいてい小さく、計算式に取り入れることが困難だという単純な事実に気づいた。 汎用性がないのでこのフィルタは破棄。 *このフィルタの将来性 差分をあらわす、ベクトル束ではなく、2つの絵の色の砂山を似せたほうがまだましだと気がついた、となると古典的な処理ってわけだ。 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication4 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { pictFilter2 PF = new pictFilter2(100d, pictureBox1); Bitmap b2 = new Bitmap(pictureBox1.Image); PF.Add_Color_frequency_table(b2); } } public class pictFilter2 { cell_date[, ,] Cells; PictureBox outPictureBox; double cell_size; Bitmap b2;//このデータにフィルタが施される Bitmap outBit; Random rnd=new Random() ; public pictFilter2(double cell_size1,PictureBox p1) { int areaCount=(int)Math.Floor(510 / cell_size1) + 3; outPictureBox = p1; Cells = new cell_date[areaCount, areaCount, areaCount]; for (int i = 0; i < areaCount; i++) { for (int j = 0; j < areaCount; j++) { for (int k = 0; k < areaCount; k++) { Cells[i, j, k] = new cell_date(); } } } this.cell_size = cell_size1; } public void Add_Color_frequency_table(Bitmap b1) { Color CD, CR, CC;//CCが今の升目で後は下、右 for (int i = 0; i < b1.Width-1; i++) { for (int j = 0; j < b1.Height-1; j++) { //イラストフィルタなので数学的厳密さは求めずに適当にデータを取ってます CC = b1.GetPixel(i, j); CD = b1.GetPixel(i, j + 1); CR = b1.GetPixel(i + 1, j); addCellDate(CC, CD); addCellDate(CC, CR); } } } public void set_Pict(Bitmap inBit) { //フィルタをかけるイラストをセットするだけの処理 b2 = inBit; outBit.Dispose(); } public void get_sandMax() { //差分フィルタ } public void addCellDate(Color C1, Color C2) { int r,g,b; r = C1.R - C2.R; g = C1.G - C2.G; b = C1.B - C2.B; this.Cells[getCell_Point(r) ,getCell_Point(g),getCell_Point(b)].add(r,g,b); } public int getCell_Point(int rgb) { return (int)Math.Floor((rgb + 255) /this.cell_size ) + 1; } public cell_date getMaxCountCell(sabunRGB sabun) { List<cell_date> cell_list = new List<cell_date>(); // int maxCount = 1; cell_date cell; //Countのうち最も大きい差分を返す処理 for (int i = -1; i < 1; i++) { for (int j = -1; j < 1; j++) { for (int k = -1; k < 1; k++) { cell = Cells[sabun.Rpoint + i, sabun.Gpoint + j, sabun.Bpoint + k]; if (maxCount < cell.getCount()) { cell_list.Clear(); cell_list.Add(cell); maxCount = cell.getCount(); }else if(maxCount==cell.getCount()){ cell_list.Add(cell); } } } } if (cell_list.Count > 0) { return (cell_list.ElementAt(rnd.Next(cell_list.Count ))); } else { return (new cell_date()); } } public sabunRGB getCellPoint2(Color C1, Color C2) { //近傍点のどれかのピクセルとの差分を計算するためのBean(Java用語) sabunRGB rgb= new sabunRGB(); rgb.sabunR =C1.R-C2.R; rgb.sabunG =C1.G-C2.G; rgb.sabunB =C1.B-C2.B; rgb.Rpoint = getCell_Point((int)(rgb.sabunR)); rgb.Gpoint = getCell_Point((int)(rgb.sabunG)); rgb.Bpoint = getCell_Point((int)(rgb.sabunB)); return rgb; } public void sand_moveFilter1() { //差分空間の近傍から一番頻度の大きい差分を選ぶ処理 Color CD, CR, CC; int [,]nextBit=new int[this.b2.Width,this.b2.Height*3];//計算の中間段階を保持するためのint for (int i = 0; i < this.b2.Width; i++) { for (int j = 0; j < this.b2.Height * 3; j++) { nextBit[i, j] = 0; } } //List<cell_date> cell_list = new List<cell_date>(); // sabunRGB sabun =new sabunRGB() ; cell_date getCell; sabunRGB aveSabun; for (int i = 0; i < b2.Width-1; i++) { for (int j = 0; j < b2.Height-1; j++) { // CC = b2.GetPixel(i, j); CD = b2.GetPixel(i, j + 1); CR = b2.GetPixel(i + 1, j); sabun=getCellPoint2(CC, CD); getCell =getMaxCountCell(sabun); aveSabun=getCell.aveSabunColor(); //フィルタ後結果を計算するため nextBitに計算結果を足していく処理 nextBit[i, j * 3 + 0] += 0.125*(aveSabun.sabunR * 0.8 + sabun.sabunR*0.2+CC.R+CD.R);   } } } public void sand_miveFilter2() { //差分空間の近傍から最頻値を平均的な確率で差分を修正する処理 } public void sand_miveFilter3() { //差分空間の近傍から最頻値を取り更に上下左右のマスとの平均を足す } public void sand_miveFilter4() { //砂山遊びにヒントを得た処理 2枚の絵の差分を移動して近づける処理 //言うは安し具体的な操作に落とすは難しい } } public class sabunRGB { public int sabunR;//移動前の位置と移動後の位置両方に使う public int sabunG; public int sabunB; public int Rpoint, Gpoint, Bpoint; public int x, y;//差分移動前の元データのピクセル座標、砂遊びフィルタ=sand_miveFilter4で使う } public class cell_date { int sumR =0; int sumG =0; int sumB =0; int count=0; public int getCount() { return count; } public void add(int r, int g, int b) { count++; sumR += r; sumG += g; sumB += b; } public void add(Color C){ count++; sumR += C.R; sumG += C.G; sumB += C.B; } public sabunRGB aveSabunColor() { if (count > 0) { sabunRGB sabun = new sabunRGB(); sabun.sabunR = sumR / count; sabun.sabunG = sumG / count; sabun.sabunB = sumB / count; return sabun; }else{ return (new sabunRGB()); } } } }

表示オプション

横に並べて表示:
変化行の前後のみ表示: