「色使いまねフィルタ」の編集履歴(バックアップ)一覧はこちら

色使いまねフィルタ」(2010/06/24 (木) 19:20:42) の最新版変更点

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

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

C#プログラム 製作者 堀江伸一 pictureBox2つ、ボタン3つおいて使うサンプルフィルタ。 ボタン2を押すとダイアログが出るので、フィルタの教師データとなる画像を選択。 ボタン3も押すと、フィルタが適用される画像が準備される。 ボタン1を押すと、フィルタが適用される。 ボタン1を押すと、ボタン3で用意した画像からカラーテーブルが作成され、フィルタされる画像をそのカラーテーブルに近づける処理が実行される。 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; using System.Threading; public delegate void ExampleCallback(Bitmap outBit, PictureBox p1); namespace WindowsFormsApplication2 { public partial class Form1 : Form { int tc = 0; //Bitmap lastB; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { pictureBox2.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/11033455_m.jpg"); } private void button1_Click(object sender, EventArgs e) { Bitmap b2 = new Bitmap(pictureBox1.Image); Bitmap b1 = new Bitmap(pictureBox2.Image); //pictureBox1.Image =b1; pictFilter PTC1 = new WindowsFormsApplication2.pictFilter(); //pict_RGB_And_Deviation aveDev = new pict_RGB_And_Deviation(150, 150, 150, 70, 70, 70); //上記メソッドは //b2 = PTC1.cercleChange(b2); //b1 = PTC1.cercleChange(b1); //pictureBox1.Image = b2; pictureBox1.Image= PTC1.Color_imitation_filter(b1,b2,10); //pictureBox1.Image = PTC1.standard_deviation_filter(aveDev, b2); //pictureBox1.Image =PTC1.lineFilter(b1); //b1=PTC1.lineFilter(b1); /*pictFilter PTC = new WindowsFormsApplication2.pictFilter(PTC1.lineFilter (b1), new ExampleCallback(ResultCallback),pictureBox1); Thread t1 =new Thread(new ThreadStart(PTC.cercleChange)); t1.Start(); t1.Join(); */ //pictFilter PTC = new WindowsFormsApplication2.pictFilter(); //pictureBox1.Image = PTC.lineFilter(b1); //pictureBox1.Image = PTC.flatFilter2( PTC.cercleChange (b1)) ; //b1.Dispose(); } public static void ResultCallback(Bitmap outBit, PictureBox p1) { p1.Image = outBit; } private void pictureBox1_Click(object sender, EventArgs e) { tc++; pictureBox1.Top = 0; pictureBox1.Left = 0; } private void button2_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "画像ファイル(*.jpeg;*.jpg;*.gif)|*.jpeg;*.jpg;*.gif|すべてのファイル(*.*)|*.*"; if (ofd.ShowDialog() == DialogResult.OK) { pictureBox2.Image = Image.FromFile(ofd.FileName); } } private void button3_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "画像ファイル(*.jpeg;*.jpg;*.gif)|*.jpeg;*.jpg;*.gif|すべてのファイル(*.*)|*.*"; if (ofd.ShowDialog() == DialogResult.OK) { pictureBox1.Image = Image.FromFile(ofd.FileName); } } } class pictFilter { Random rnd = new Random(); Bitmap pictOut = null; int h;//絵の高さ int w;//絵の横幅 Bitmap pictIn; ExampleCallback callback; PictureBox lastPict; cell[, ,] cells; int cell_size; public pictFilter() { h = 0; w = 0; } public Bitmap Color_imitation_filter(Bitmap b1, Bitmap b2,int c_size) { cell_size = c_size; int size=255/cell_size+5; cells = new cell[size, size, size]; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { for (int k = 0; k < size; k++) { cells[i, j, k] = new cell(); } } } pict_RGB_And_Deviation aveDev1=new pict_RGB_And_Deviation(b1); pict_RGB_And_Deviation aveDev2 = new pict_RGB_And_Deviation(b2); int sabunR =(int)Math.Floor ( aveDev1.aveR - aveDev2.aveR); int sabunG =(int)Math.Floor ( aveDev1.aveG - aveDev2.aveG); int sabunB = (int)Math.Floor(aveDev1.aveB - aveDev2.aveB); Color C1; Bitmap b3=new Bitmap (b2.Width,b2.Height ); for (int i = 0; i < b1.Width; i++) { for (int j = 0; j < b1.Height; j++) { C1 = b1.GetPixel(i, j); cells[get_cell_point(C1.R), get_cell_point(C1.G), get_cell_point(C1.B)].add(C1.R, C1.G, C1.B); } } Color nextColor; for (int i = 0; i < b2.Width; i++) { for (int j = 0; j < b2.Height; j++) { C1 = b2.GetPixel(i, j); //nextColor=C1; nextColor =Color.FromArgb(cutNum(0, 255, C1.R + sabunR/2), cutNum(0, 255, C1.G + sabunG/2), cutNum(0, 255, C1.B + sabunB/2)); //nextColor = getAveCountCell(nextColor); nextColor = getMaxCountCell(nextColor); // b3.SetPixel(i, j, nextColor); } } return b3; } public Color getAveCountCell(Color C1) { List<cell> cell_list = new List<cell>(); // int rPoint, gPoint, bPoint; cell myCell; //Count数の比率からセルを平均的に返す処理 rPoint = get_cell_point(C1.R); gPoint = get_cell_point(C1.G); bPoint = get_cell_point(C1.B); int sumCount=0; for (int i = -2; i < 3; i++) { for (int j = -2; j < 3; j++) { for (int k = -2; k < 3; k++) { myCell = cells[rPoint+i, gPoint+j, bPoint+k]; if (myCell.getCount() > 0) { cell_list.Add(myCell); sumCount +=myCell.getCount(); } } } } if (cell_list.Count > 0) { int rndC=rnd.Next(sumCount); int tSum=0; Color C2=C1; foreach (cell myCell1 in cell_list) { tSum +=myCell1.getCount(); if(tSum>rndC){ C2=myCell1.aveColor() ; break; } } return Color.FromArgb( (int)Math.Floor(C2.R * 0.1d + C1.R * 0.9d), (int)Math.Floor(C2.G * 0.1d + C1.G * 0.9d), (int)Math.Floor(C2.B * 0.1d + C1.B * 0.9d) ); } else { return C1; } } public Color getMaxCountCell(Color C1) { List<cell> cell_list = new List<cell>(); // int maxCount = 1; int rPoint,gPoint,bPoint; cell myCell; //Countが最も大きいセルを返す処理 rPoint=get_cell_point(C1.R ); gPoint=get_cell_point(C1.G); bPoint=get_cell_point (C1.B); for (int i = -2; i < 3; i++) { for (int j = -2; j < 3; j++) { for (int k = -2; k < 3; k++) { myCell=cells[rPoint+i,gPoint+j,bPoint+k]; if(myCell.getCount ()>maxCount ){ cell_list.Clear(); cell_list.Add(myCell); maxCount = myCell.getCount(); }else if(myCell.getCount ()==maxCount ){ cell_list.Add(myCell); } } } } if (cell_list.Count>0) { Color C2; C2=cell_list[rnd.Next(cell_list.Count)].aveColor() ; return Color.FromArgb( (int)Math.Floor (C2.R * 0.8d + C1.R * 0.2d), (int)Math.Floor (C2.G * 0.8d + C1.G * 0.2d), (int)Math.Floor (C2.B * 0.8d + C1.B * 0.2d) ); } else { return C1; } } public int get_cell_point(int rgb) { return (rgb / cell_size) +2; } public Bitmap standard_deviation_filter(pict_RGB_And_Deviation aveDev1, Bitmap b2) { Color C2; Bitmap outBit; double tR, tG, tB; int tR1, tG1, tB1; pict_RGB_And_Deviation aveDev2 = new pict_RGB_And_Deviation(b2); outBit = new Bitmap(b2.Width, b2.Height); for (int i = 0; i < b2.Width; i++) { for (int j = 0; j < b2.Height; j++) { C2 = b2.GetPixel(i, j); //tR = ((C2.R - aveDev2.aveR) / aveDev2.devR) * ((C2.R - aveDev2.aveR) / aveDev2.devR) * aveDev1.devR + aveDev1.aveR; //tG = ((C2.G - aveDev2.aveG) / aveDev2.devG) * (C2.G - aveDev2.aveG) / aveDev2.devG * aveDev1.devG + aveDev1.aveG; //tB = ((C2.B - aveDev2.aveB) / aveDev2.devB) * (C2.B - aveDev2.aveB) / aveDev2.devB * aveDev1.devB + aveDev1.aveB; tR = Math.Log(3 * ((C2.R - aveDev2.aveR) / aveDev2.devR)) * aveDev1.devR + aveDev1.aveR; tG = Math.Log(3 * ((C2.G - aveDev2.aveG) / aveDev2.devG)) * aveDev1.devG + aveDev1.aveG; tB = Math.Log(3 * ((C2.B - aveDev2.aveB) / aveDev2.devB)) * aveDev1.devB + aveDev1.aveB; /* tR = (C2.R - aveDev2.aveR); tR = tR / 2.0 + 0.5; if (tR > 0.5) { tR = -Math.Pow(2 * tR - 2, 0.7) / 2 + 1; } else { tR=2 * Math.Pow(tR, 0.7/2); } tR = tR * 2 - 1; */ tR1 = cutNum(0, 255, (int)Math.Floor(tR)); tG1 = cutNum(0, 255, (int)Math.Floor(tG)); tB1 = cutNum(0, 255, (int)Math.Floor(tB)); outBit.SetPixel(i, j, Color.FromArgb(tR1, tG1, tB1)); } } //生物の遺伝子構造解析をして病気対策をするとき、遺伝子コードのパターンマッチにパソコンを使うとか、本当はそういうプログラム書けたらなと思ったり、 return outBit; } public Bitmap standard_deviation_filter(Bitmap b1, Bitmap b2) { Color C2; Bitmap outBit; double tR, tG, tB; int tR1, tG1, tB1; pict_RGB_And_Deviation aveDev1 = new pict_RGB_And_Deviation(b1); pict_RGB_And_Deviation aveDev2 = new pict_RGB_And_Deviation(b2); outBit = new Bitmap(b2.Width, b2.Height); for (int i = 0; i < b2.Width; i++) { for (int j = 0; j < b2.Height; j++) { C2 = b2.GetPixel(i, j); tR = ((C2.R - aveDev2.aveR) / aveDev2.devR) * aveDev1.devR + aveDev1.aveR; tG = (C2.G - aveDev2.aveG) / aveDev2.devG * aveDev1.devG + aveDev1.aveG; tB = (C2.B - aveDev2.aveB) / aveDev2.devB * aveDev1.devB + aveDev1.aveB; //tR = ((C2.R - aveDev2.aveR) / aveDev2.devR) * ((C2.R - aveDev2.aveR) / aveDev2.devR) * aveDev1.devR + aveDev1.aveR; //tG = ((C2.G - aveDev2.aveG) / aveDev2.devG) * ((C2.G - aveDev2.aveG) / aveDev2.devG) * aveDev1.devG + aveDev1.aveG; //tB = ((C2.B - aveDev2.aveB) / aveDev2.devB) * ((C2.B - aveDev2.aveB) / aveDev2.devB) * aveDev1.devB + aveDev1.aveB; tR1 = cutNum(0, 255, (int)Math.Floor(tR)); tG1 = cutNum(0, 255, (int)Math.Floor(tG)); tB1 = cutNum(0, 255, (int)Math.Floor(tB)); outBit.SetPixel(i, j, Color.FromArgb(tR1, tG1, tB1)); } } //生物の遺伝子構造解析をして病気対策をするとき、遺伝子コードのパターンマッチにパソコンを使うとか、本当はそういうプログラム書けたらなと思ったり、 return outBit; } public pictFilter(Bitmap b1, ExampleCallback callbackDelegate, PictureBox p1) { this.pictIn = b1; h = 0; w = 0; callback = callbackDelegate; lastPict = p1; } public Bitmap cercleChange(Bitmap b1) { //各ピクセルの色空間内の位置を点(ccR,ccB,ccG)を中心に体積拡大する処理 //このメソッドはスレッドで呼ぶこと前提にしている float ccR = 128; float ccG = 128; float ccB = 128; float a = 2.0f; float b = 0.5f; double cR, cG, cB; double r1 = 0; double r2 = 0; Color C1; //double rk; this.h = b1.Height; this.w = b1.Width; Bitmap pictOut = new Bitmap(this.w, this.h); //Threadをとめる処理 for (int i = 0; i < this.w; i++) { for (int j = 0; j < this.h; j++) { C1 = b1.GetPixel(i, j); r1 = Math.Sqrt((C1.R - ccR) * (C1.R - ccR) + (C1.G - ccG) * (C1.G - ccG) + (C1.B - ccB) * (C1.B - ccB)) / 255; r2 = (a * r1 + b); cR = r2 * (C1.R - ccR) + ccR; cG = r2 * (C1.G - ccG) + ccG; cB = r2 * (C1.B - ccB) + ccB; pictOut.SetPixel(i, j, Color.FromArgb( cutNum(0, 255, (int)(cR)), cutNum(0, 255, (int)(cG)), cutNum(0, 255, (int)(cB)))); //これはLispではありませんw } } //テンプレ //this.h = pictIn.Height; //this.w = pictIn.Width; //pictOut = new Bitmap(this.w, this.h); //for(int i=0;i<this.w;i++){ // for (int j = 0; j < this.h; j++) // { // } //} return pictOut; } public void cercleChange() { //各ピクセルの色空間内の位置を点(ccR,ccB,ccG)を中心に体積拡大する処理 //このメソッドはスレッドで呼ぶこと前提にしている float ccR = 128; float ccG = 128; float ccB = 128; float a = 2.0f; float b = 0.5f; double cR, cG, cB; double r1 = 0; double r2 = 0; Color C1; //double rk; this.h = pictIn.Height; this.w = pictIn.Width; pictOut = new Bitmap(this.w, this.h); //Threadをとめる処理 for (int i = 0; i < this.w; i++) { for (int j = 0; j < this.h; j++) { C1 = pictIn.GetPixel(i, j); r1 = Math.Sqrt((C1.R - ccR) * (C1.R - ccR) + (C1.G - ccG) * (C1.G - ccG) + (C1.B - ccB) * (C1.B - ccB)) / 255; r2 = (a * r1 + b); cR = r2 * (C1.R - ccR) + ccR; cG = r2 * (C1.G - ccG) + ccG; cB = r2 * (C1.B - ccB) + ccB; pictOut.SetPixel(i, j, Color.FromArgb( cutNum(0, 255, (int)(cR)), cutNum(0, 255, (int)(cG)), cutNum(0, 255, (int)(cB)))); //これはLispではありませんw } if (i % 10 == 0) { Thread.Sleep(30); } } //スレッドのOutput用命令 callback(pictOut, lastPict); //テンプレ //this.h = pictIn.Height; //this.w = pictIn.Width; //pictOut = new Bitmap(this.w, this.h); //for(int i=0;i<this.w;i++){ // for (int j = 0; j < this.h; j++) // { // } //} //return pictOut; } public Bitmap flatFilter2(Bitmap pictIn) { //色空間内の点の色座標をを法線ベクトル(1,1,1),rgbAve=r+g+bとなる平面から遠くへ引き離したり、近づけたりする処理 Color C1; this.h = pictIn.Height; this.w = pictIn.Width; double flatLen = 0; double r1 = 0; float rgbAve = 256; pictOut = new Bitmap(this.w, this.h); double a = -1.0; double b = 2.0; double root3 = Math.Sqrt(3); double v1 = 184; double maxRGB = 0, minRGB = 0; for (int i = 0; i < this.w; i++) { for (int j = 0; j < this.h; j++) { C1 = pictIn.GetPixel(i, j); flatLen = (C1.R + C1.G + C1.B - rgbAve) / (root3); //点と平面までの距離 r1 = Math.Sign(flatLen) * ((a * Math.Abs(flatLen) / v1 + b));//点と平面までの距離に基づいて、次の点の平面からの距離を決定する。 maxRGB = Math.Max(C1.R + r1 * v1, Math.Max(C1.G + r1 * v1, C1.B + r1 * v1)); if (maxRGB > 255) { if (C1.R > C1.G && C1.R > C1.B) { r1 = r1 - (255 - C1.R) / v1 - 1; } else if (C1.G > C1.R && C1.G > C1.B) { r1 = r1 - (255 - C1.G) / v1 - 1; } else { r1 = r1 - (255 - C1.B) / v1 - 1; } } minRGB = Math.Min(C1.R + r1 * v1, Math.Min(C1.G + r1 * v1, C1.B + r1 * v1)); if (minRGB < 0) { if (C1.R < C1.G && C1.R < C1.B) { r1 = r1 - (C1.R) / v1 - 1; } else if (C1.G < C1.R && C1.G < C1.B) { r1 = r1 - (C1.G) / v1 - 1; } else { r1 = r1 - (C1.B) / v1 - 1; } } pictOut.SetPixel(i, j, Color.FromArgb( cutNum(0, 255, (int)(C1.R + r1 * v1)), cutNum(0, 255, (int)(C1.G + r1 * v1)), cutNum(0, 255, (int)(C1.B + r1 * v1)))); } } return pictOut; } public Bitmap adsorptionFilter(Bitmap pictIn) { //テンプレ Color C1; this.h = pictIn.Height; this.w = pictIn.Width; pictOut = new Bitmap(this.w, this.h); byte maxRGB; byte minRGB; double rgbR, rgbG, rgbB; for (int i = 0; i < this.w; i++) { for (int j = 0; j < this.h; j++) { C1 = pictIn.GetPixel(i, j); rgbR = C1.R; rgbG = C1.G; rgbB = C1.B; maxRGB = (byte)Math.Max(rgbR, Math.Max(rgbG, rgbB)); minRGB = (byte)Math.Min(rgbR, Math.Min(rgbG, rgbB)); if (255 - maxRGB < minRGB) { if (rgbR == maxRGB) { rgbR = 255 * 0.5 + rgbR * 0.5; } else if (rgbB == maxRGB) { rgbB = 255 * 0.5 + rgbB * 0.5; } else { rgbG = 255 * 0.5 + rgbG * 0.5; } } else { if (C1.R == minRGB) { rgbR = rgbR * 0.5; } else if (C1.G == minRGB) { rgbG = rgbG * 0.5; } else { rgbB = rgbB * 0.5; } } pictOut.SetPixel(i, j, Color.FromArgb( (int)rgbR, (int)rgbG, (int)rgbB)); } } return pictOut; } public Bitmap lineFilter(Bitmap pictIn) { //テンプレ Color C1; this.h = pictIn.Height; this.w = pictIn.Width; double r1; double r2; double[] vecOB = { -1, -1, 1 }; double[] vecOH = { 0, 0, 0 }; double[] vecOA = { 0, 0, 0 }; double[] vecHA = { 0, 0, 0 }; double[] vecOA2 = { 0, 0, 0 }; double[] vecCen = { 255, 255, 0 }; double LenOH, LenOB, LenHA = 0; double a = -1.0; double b = 2.0; LenOB = Math.Sqrt(vecOB[0] * vecOB[0] + vecOB[1] * vecOB[1] + vecOB[2] * vecOB[2]); pictOut = new Bitmap(this.w, this.h); for (int i = 0; i < this.w; i++) { for (int j = 0; j < this.h; j++) { LenHA = 0; C1 = pictIn.GetPixel(i, j); vecOA[0] = C1.R - vecCen[0]; vecOA[1] = C1.G - vecCen[1]; vecOA[2] = C1.B - vecCen[2]; LenOH = (vecOA[0] * vecOB[0] + vecOA[1] * vecOB[1] + vecOA[2] * vecOB[2]) / LenOB; for (int k = 0; k < 3; k++) { vecOH[k] = LenOH / LenOB * vecOB[k]; vecHA[k] = -vecOH[k] + vecOA[k]; LenHA += vecHA[k] * vecHA[k]; } LenHA = Math.Sqrt(LenHA); r1 = LenHA / 255; r2 = (a * r1 + b); for (int k = 0; k < 3; k++) { //vecOA2[k] = cutNum(0,255,(int)( r2 * vecHA[k] + vecOH[k]+vecCen[k])); vecOA2[k] = cutNum(0, 255, (int)(r2 * vecHA[k] * 0 + vecOH[k] + vecCen[k])); } pictOut.SetPixel(i, j, Color.FromArgb( (int)vecOA2[0], (int)vecOA2[1], (int)vecOA2[2])); } } return pictOut; } public Bitmap flatFilter(Bitmap pictIn) { //テンプレ Color C1; this.h = pictIn.Height; this.w = pictIn.Width; int rgbR, rgbG, rgbB; pictOut = new Bitmap(this.w, this.h); for (int i = 0; i < this.w; i++) { for (int j = 0; j < this.h; j++) { C1 = pictIn.GetPixel(i, j); if (C1.R + C1.G + C1.B > 255) { rgbR = (int)(C1.R * 0.5 + 255 * 0.5); rgbG = (int)(C1.G * 0.5 + 255 * 0.5); rgbB = (int)(C1.B * 0.5 + 255 * 0.5); } else { rgbR = (int)(C1.R * 0.5); rgbG = (int)(C1.G * 0.5); rgbB = (int)(C1.B * 0.5); } pictOut.SetPixel(i, j, Color.FromArgb(rgbR, rgbG, rgbB)); } } return pictOut; } private int cutNum(int min, int max, int t) { if (t < min) { t = min; } if (t > max) { t = max; } return t; } } public class pict_RGB_And_Deviation { public double aveR, aveG, aveB; public double devR, devG, devB; public pict_RGB_And_Deviation(double inAveR, double inAveG, double inAveB, double inDevR, double inDevG, double inDevB) { aveR = inAveR; aveG = inAveG; aveB = inAveB; devR = inDevR; devG = inDevG; devB = inDevB; } public pict_RGB_And_Deviation(Bitmap b1) { Color C1; double countPictSize; for (int i = 0; i < b1.Width; i++) { for (int j = 0; j < b1.Height; j++) { C1 = b1.GetPixel(i, j); aveR += (double)C1.R; aveG += (double)C1.G; aveB += (double)C1.B; } } countPictSize = b1.Width * b1.Height; aveR /= countPictSize; aveG /= countPictSize; aveB /= countPictSize; for (int i = 0; i < b1.Width; i++) { for (int j = 0; j < b1.Height; j++) { C1 = b1.GetPixel(i, j); devR += ((double)C1.R - aveR) * ((double)C1.R - aveR); devG += ((double)C1.G - aveG) * ((double)C1.G - aveG); devB += ((double)C1.B - aveB) * ((double)C1.B - aveB); } } if (countPictSize > 1) { countPictSize--; } else { countPictSize = 1; } devR = Math.Sqrt(devR / countPictSize); devG = Math.Sqrt(devG / countPictSize); devB = Math.Sqrt(devB / countPictSize); } } public class cell { 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 Color aveColor() { if (count > 0) { return Color.FromArgb( (int)sumR/count, (int)sumG/count, (int)sumB/count) ; }else{ return (Color.FromArgb(0,0,0) ); } } } }
C#プログラム 製作者 堀江伸一 [[色使いまねフィルタ2]] pictureBox2つ、ボタン3つおいて使うサンプルフィルタ。 ボタン2を押すとダイアログが出るので、フィルタの教師データとなる画像を選択。 ボタン3も押すと、フィルタが適用される画像が準備される。 ボタン1を押すと、フィルタが適用される。 ボタン1を押すと、ボタン3で用意した画像からカラーテーブルが作成され、フィルタされる画像をそのカラーテーブルに近づける処理が実行される。 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; using System.Threading; public delegate void ExampleCallback(Bitmap outBit, PictureBox p1); namespace WindowsFormsApplication2 { public partial class Form1 : Form { int tc = 0; //Bitmap lastB; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { pictureBox2.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/11033455_m.jpg"); } private void button1_Click(object sender, EventArgs e) { Bitmap b2 = new Bitmap(pictureBox1.Image); Bitmap b1 = new Bitmap(pictureBox2.Image); //pictureBox1.Image =b1; pictFilter PTC1 = new WindowsFormsApplication2.pictFilter(); //pict_RGB_And_Deviation aveDev = new pict_RGB_And_Deviation(150, 150, 150, 70, 70, 70); //上記メソッドは //b2 = PTC1.cercleChange(b2); //b1 = PTC1.cercleChange(b1); //pictureBox1.Image = b2; pictureBox1.Image= PTC1.Color_imitation_filter(b1,b2,10); //pictureBox1.Image = PTC1.standard_deviation_filter(aveDev, b2); //pictureBox1.Image =PTC1.lineFilter(b1); //b1=PTC1.lineFilter(b1); /*pictFilter PTC = new WindowsFormsApplication2.pictFilter(PTC1.lineFilter (b1), new ExampleCallback(ResultCallback),pictureBox1); Thread t1 =new Thread(new ThreadStart(PTC.cercleChange)); t1.Start(); t1.Join(); */ //pictFilter PTC = new WindowsFormsApplication2.pictFilter(); //pictureBox1.Image = PTC.lineFilter(b1); //pictureBox1.Image = PTC.flatFilter2( PTC.cercleChange (b1)) ; //b1.Dispose(); } public static void ResultCallback(Bitmap outBit, PictureBox p1) { p1.Image = outBit; } private void pictureBox1_Click(object sender, EventArgs e) { tc++; pictureBox1.Top = 0; pictureBox1.Left = 0; } private void button2_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "画像ファイル(*.jpeg;*.jpg;*.gif)|*.jpeg;*.jpg;*.gif|すべてのファイル(*.*)|*.*"; if (ofd.ShowDialog() == DialogResult.OK) { pictureBox2.Image = Image.FromFile(ofd.FileName); } } private void button3_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "画像ファイル(*.jpeg;*.jpg;*.gif)|*.jpeg;*.jpg;*.gif|すべてのファイル(*.*)|*.*"; if (ofd.ShowDialog() == DialogResult.OK) { pictureBox1.Image = Image.FromFile(ofd.FileName); } } } class pictFilter { Random rnd = new Random(); Bitmap pictOut = null; int h;//絵の高さ int w;//絵の横幅 Bitmap pictIn; ExampleCallback callback; PictureBox lastPict; cell[, ,] cells; int cell_size; public pictFilter() { h = 0; w = 0; } public Bitmap Color_imitation_filter(Bitmap b1, Bitmap b2,int c_size) { cell_size = c_size; int size=255/cell_size+5; cells = new cell[size, size, size]; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { for (int k = 0; k < size; k++) { cells[i, j, k] = new cell(); } } } pict_RGB_And_Deviation aveDev1=new pict_RGB_And_Deviation(b1); pict_RGB_And_Deviation aveDev2 = new pict_RGB_And_Deviation(b2); int sabunR =(int)Math.Floor ( aveDev1.aveR - aveDev2.aveR); int sabunG =(int)Math.Floor ( aveDev1.aveG - aveDev2.aveG); int sabunB = (int)Math.Floor(aveDev1.aveB - aveDev2.aveB); Color C1; Bitmap b3=new Bitmap (b2.Width,b2.Height ); for (int i = 0; i < b1.Width; i++) { for (int j = 0; j < b1.Height; j++) { C1 = b1.GetPixel(i, j); cells[get_cell_point(C1.R), get_cell_point(C1.G), get_cell_point(C1.B)].add(C1.R, C1.G, C1.B); } } Color nextColor; for (int i = 0; i < b2.Width; i++) { for (int j = 0; j < b2.Height; j++) { C1 = b2.GetPixel(i, j); //nextColor=C1; nextColor =Color.FromArgb(cutNum(0, 255, C1.R + sabunR/2), cutNum(0, 255, C1.G + sabunG/2), cutNum(0, 255, C1.B + sabunB/2)); //nextColor = getAveCountCell(nextColor); nextColor = getMaxCountCell(nextColor); // b3.SetPixel(i, j, nextColor); } } return b3; } public Color getAveCountCell(Color C1) { List<cell> cell_list = new List<cell>(); // int rPoint, gPoint, bPoint; cell myCell; //Count数の比率からセルを平均的に返す処理 rPoint = get_cell_point(C1.R); gPoint = get_cell_point(C1.G); bPoint = get_cell_point(C1.B); int sumCount=0; for (int i = -2; i < 3; i++) { for (int j = -2; j < 3; j++) { for (int k = -2; k < 3; k++) { myCell = cells[rPoint+i, gPoint+j, bPoint+k]; if (myCell.getCount() > 0) { cell_list.Add(myCell); sumCount +=myCell.getCount(); } } } } if (cell_list.Count > 0) { int rndC=rnd.Next(sumCount); int tSum=0; Color C2=C1; foreach (cell myCell1 in cell_list) { tSum +=myCell1.getCount(); if(tSum>rndC){ C2=myCell1.aveColor() ; break; } } return Color.FromArgb( (int)Math.Floor(C2.R * 0.1d + C1.R * 0.9d), (int)Math.Floor(C2.G * 0.1d + C1.G * 0.9d), (int)Math.Floor(C2.B * 0.1d + C1.B * 0.9d) ); } else { return C1; } } public Color getMaxCountCell(Color C1) { List<cell> cell_list = new List<cell>(); // int maxCount = 1; int rPoint,gPoint,bPoint; cell myCell; //Countが最も大きいセルを返す処理 rPoint=get_cell_point(C1.R ); gPoint=get_cell_point(C1.G); bPoint=get_cell_point (C1.B); for (int i = -2; i < 3; i++) { for (int j = -2; j < 3; j++) { for (int k = -2; k < 3; k++) { myCell=cells[rPoint+i,gPoint+j,bPoint+k]; if(myCell.getCount ()>maxCount ){ cell_list.Clear(); cell_list.Add(myCell); maxCount = myCell.getCount(); }else if(myCell.getCount ()==maxCount ){ cell_list.Add(myCell); } } } } if (cell_list.Count>0) { Color C2; C2=cell_list[rnd.Next(cell_list.Count)].aveColor() ; return Color.FromArgb( (int)Math.Floor (C2.R * 0.8d + C1.R * 0.2d), (int)Math.Floor (C2.G * 0.8d + C1.G * 0.2d), (int)Math.Floor (C2.B * 0.8d + C1.B * 0.2d) ); } else { return C1; } } public int get_cell_point(int rgb) { return (rgb / cell_size) +2; } public Bitmap standard_deviation_filter(pict_RGB_And_Deviation aveDev1, Bitmap b2) { Color C2; Bitmap outBit; double tR, tG, tB; int tR1, tG1, tB1; pict_RGB_And_Deviation aveDev2 = new pict_RGB_And_Deviation(b2); outBit = new Bitmap(b2.Width, b2.Height); for (int i = 0; i < b2.Width; i++) { for (int j = 0; j < b2.Height; j++) { C2 = b2.GetPixel(i, j); //tR = ((C2.R - aveDev2.aveR) / aveDev2.devR) * ((C2.R - aveDev2.aveR) / aveDev2.devR) * aveDev1.devR + aveDev1.aveR; //tG = ((C2.G - aveDev2.aveG) / aveDev2.devG) * (C2.G - aveDev2.aveG) / aveDev2.devG * aveDev1.devG + aveDev1.aveG; //tB = ((C2.B - aveDev2.aveB) / aveDev2.devB) * (C2.B - aveDev2.aveB) / aveDev2.devB * aveDev1.devB + aveDev1.aveB; tR = Math.Log(3 * ((C2.R - aveDev2.aveR) / aveDev2.devR)) * aveDev1.devR + aveDev1.aveR; tG = Math.Log(3 * ((C2.G - aveDev2.aveG) / aveDev2.devG)) * aveDev1.devG + aveDev1.aveG; tB = Math.Log(3 * ((C2.B - aveDev2.aveB) / aveDev2.devB)) * aveDev1.devB + aveDev1.aveB; /* tR = (C2.R - aveDev2.aveR); tR = tR / 2.0 + 0.5; if (tR > 0.5) { tR = -Math.Pow(2 * tR - 2, 0.7) / 2 + 1; } else { tR=2 * Math.Pow(tR, 0.7/2); } tR = tR * 2 - 1; */ tR1 = cutNum(0, 255, (int)Math.Floor(tR)); tG1 = cutNum(0, 255, (int)Math.Floor(tG)); tB1 = cutNum(0, 255, (int)Math.Floor(tB)); outBit.SetPixel(i, j, Color.FromArgb(tR1, tG1, tB1)); } } //生物の遺伝子構造解析をして病気対策をするとき、遺伝子コードのパターンマッチにパソコンを使うとか、本当はそういうプログラム書けたらなと思ったり、 return outBit; } public Bitmap standard_deviation_filter(Bitmap b1, Bitmap b2) { Color C2; Bitmap outBit; double tR, tG, tB; int tR1, tG1, tB1; pict_RGB_And_Deviation aveDev1 = new pict_RGB_And_Deviation(b1); pict_RGB_And_Deviation aveDev2 = new pict_RGB_And_Deviation(b2); outBit = new Bitmap(b2.Width, b2.Height); for (int i = 0; i < b2.Width; i++) { for (int j = 0; j < b2.Height; j++) { C2 = b2.GetPixel(i, j); tR = ((C2.R - aveDev2.aveR) / aveDev2.devR) * aveDev1.devR + aveDev1.aveR; tG = (C2.G - aveDev2.aveG) / aveDev2.devG * aveDev1.devG + aveDev1.aveG; tB = (C2.B - aveDev2.aveB) / aveDev2.devB * aveDev1.devB + aveDev1.aveB; //tR = ((C2.R - aveDev2.aveR) / aveDev2.devR) * ((C2.R - aveDev2.aveR) / aveDev2.devR) * aveDev1.devR + aveDev1.aveR; //tG = ((C2.G - aveDev2.aveG) / aveDev2.devG) * ((C2.G - aveDev2.aveG) / aveDev2.devG) * aveDev1.devG + aveDev1.aveG; //tB = ((C2.B - aveDev2.aveB) / aveDev2.devB) * ((C2.B - aveDev2.aveB) / aveDev2.devB) * aveDev1.devB + aveDev1.aveB; tR1 = cutNum(0, 255, (int)Math.Floor(tR)); tG1 = cutNum(0, 255, (int)Math.Floor(tG)); tB1 = cutNum(0, 255, (int)Math.Floor(tB)); outBit.SetPixel(i, j, Color.FromArgb(tR1, tG1, tB1)); } } //生物の遺伝子構造解析をして病気対策をするとき、遺伝子コードのパターンマッチにパソコンを使うとか、本当はそういうプログラム書けたらなと思ったり、 return outBit; } public pictFilter(Bitmap b1, ExampleCallback callbackDelegate, PictureBox p1) { this.pictIn = b1; h = 0; w = 0; callback = callbackDelegate; lastPict = p1; } public Bitmap cercleChange(Bitmap b1) { //各ピクセルの色空間内の位置を点(ccR,ccB,ccG)を中心に体積拡大する処理 //このメソッドはスレッドで呼ぶこと前提にしている float ccR = 128; float ccG = 128; float ccB = 128; float a = 2.0f; float b = 0.5f; double cR, cG, cB; double r1 = 0; double r2 = 0; Color C1; //double rk; this.h = b1.Height; this.w = b1.Width; Bitmap pictOut = new Bitmap(this.w, this.h); //Threadをとめる処理 for (int i = 0; i < this.w; i++) { for (int j = 0; j < this.h; j++) { C1 = b1.GetPixel(i, j); r1 = Math.Sqrt((C1.R - ccR) * (C1.R - ccR) + (C1.G - ccG) * (C1.G - ccG) + (C1.B - ccB) * (C1.B - ccB)) / 255; r2 = (a * r1 + b); cR = r2 * (C1.R - ccR) + ccR; cG = r2 * (C1.G - ccG) + ccG; cB = r2 * (C1.B - ccB) + ccB; pictOut.SetPixel(i, j, Color.FromArgb( cutNum(0, 255, (int)(cR)), cutNum(0, 255, (int)(cG)), cutNum(0, 255, (int)(cB)))); //これはLispではありませんw } } //テンプレ //this.h = pictIn.Height; //this.w = pictIn.Width; //pictOut = new Bitmap(this.w, this.h); //for(int i=0;i<this.w;i++){ // for (int j = 0; j < this.h; j++) // { // } //} return pictOut; } public void cercleChange() { //各ピクセルの色空間内の位置を点(ccR,ccB,ccG)を中心に体積拡大する処理 //このメソッドはスレッドで呼ぶこと前提にしている float ccR = 128; float ccG = 128; float ccB = 128; float a = 2.0f; float b = 0.5f; double cR, cG, cB; double r1 = 0; double r2 = 0; Color C1; //double rk; this.h = pictIn.Height; this.w = pictIn.Width; pictOut = new Bitmap(this.w, this.h); //Threadをとめる処理 for (int i = 0; i < this.w; i++) { for (int j = 0; j < this.h; j++) { C1 = pictIn.GetPixel(i, j); r1 = Math.Sqrt((C1.R - ccR) * (C1.R - ccR) + (C1.G - ccG) * (C1.G - ccG) + (C1.B - ccB) * (C1.B - ccB)) / 255; r2 = (a * r1 + b); cR = r2 * (C1.R - ccR) + ccR; cG = r2 * (C1.G - ccG) + ccG; cB = r2 * (C1.B - ccB) + ccB; pictOut.SetPixel(i, j, Color.FromArgb( cutNum(0, 255, (int)(cR)), cutNum(0, 255, (int)(cG)), cutNum(0, 255, (int)(cB)))); //これはLispではありませんw } if (i % 10 == 0) { Thread.Sleep(30); } } //スレッドのOutput用命令 callback(pictOut, lastPict); //テンプレ //this.h = pictIn.Height; //this.w = pictIn.Width; //pictOut = new Bitmap(this.w, this.h); //for(int i=0;i<this.w;i++){ // for (int j = 0; j < this.h; j++) // { // } //} //return pictOut; } public Bitmap flatFilter2(Bitmap pictIn) { //色空間内の点の色座標をを法線ベクトル(1,1,1),rgbAve=r+g+bとなる平面から遠くへ引き離したり、近づけたりする処理 Color C1; this.h = pictIn.Height; this.w = pictIn.Width; double flatLen = 0; double r1 = 0; float rgbAve = 256; pictOut = new Bitmap(this.w, this.h); double a = -1.0; double b = 2.0; double root3 = Math.Sqrt(3); double v1 = 184; double maxRGB = 0, minRGB = 0; for (int i = 0; i < this.w; i++) { for (int j = 0; j < this.h; j++) { C1 = pictIn.GetPixel(i, j); flatLen = (C1.R + C1.G + C1.B - rgbAve) / (root3); //点と平面までの距離 r1 = Math.Sign(flatLen) * ((a * Math.Abs(flatLen) / v1 + b));//点と平面までの距離に基づいて、次の点の平面からの距離を決定する。 maxRGB = Math.Max(C1.R + r1 * v1, Math.Max(C1.G + r1 * v1, C1.B + r1 * v1)); if (maxRGB > 255) { if (C1.R > C1.G && C1.R > C1.B) { r1 = r1 - (255 - C1.R) / v1 - 1; } else if (C1.G > C1.R && C1.G > C1.B) { r1 = r1 - (255 - C1.G) / v1 - 1; } else { r1 = r1 - (255 - C1.B) / v1 - 1; } } minRGB = Math.Min(C1.R + r1 * v1, Math.Min(C1.G + r1 * v1, C1.B + r1 * v1)); if (minRGB < 0) { if (C1.R < C1.G && C1.R < C1.B) { r1 = r1 - (C1.R) / v1 - 1; } else if (C1.G < C1.R && C1.G < C1.B) { r1 = r1 - (C1.G) / v1 - 1; } else { r1 = r1 - (C1.B) / v1 - 1; } } pictOut.SetPixel(i, j, Color.FromArgb( cutNum(0, 255, (int)(C1.R + r1 * v1)), cutNum(0, 255, (int)(C1.G + r1 * v1)), cutNum(0, 255, (int)(C1.B + r1 * v1)))); } } return pictOut; } public Bitmap adsorptionFilter(Bitmap pictIn) { //テンプレ Color C1; this.h = pictIn.Height; this.w = pictIn.Width; pictOut = new Bitmap(this.w, this.h); byte maxRGB; byte minRGB; double rgbR, rgbG, rgbB; for (int i = 0; i < this.w; i++) { for (int j = 0; j < this.h; j++) { C1 = pictIn.GetPixel(i, j); rgbR = C1.R; rgbG = C1.G; rgbB = C1.B; maxRGB = (byte)Math.Max(rgbR, Math.Max(rgbG, rgbB)); minRGB = (byte)Math.Min(rgbR, Math.Min(rgbG, rgbB)); if (255 - maxRGB < minRGB) { if (rgbR == maxRGB) { rgbR = 255 * 0.5 + rgbR * 0.5; } else if (rgbB == maxRGB) { rgbB = 255 * 0.5 + rgbB * 0.5; } else { rgbG = 255 * 0.5 + rgbG * 0.5; } } else { if (C1.R == minRGB) { rgbR = rgbR * 0.5; } else if (C1.G == minRGB) { rgbG = rgbG * 0.5; } else { rgbB = rgbB * 0.5; } } pictOut.SetPixel(i, j, Color.FromArgb( (int)rgbR, (int)rgbG, (int)rgbB)); } } return pictOut; } public Bitmap lineFilter(Bitmap pictIn) { //テンプレ Color C1; this.h = pictIn.Height; this.w = pictIn.Width; double r1; double r2; double[] vecOB = { -1, -1, 1 }; double[] vecOH = { 0, 0, 0 }; double[] vecOA = { 0, 0, 0 }; double[] vecHA = { 0, 0, 0 }; double[] vecOA2 = { 0, 0, 0 }; double[] vecCen = { 255, 255, 0 }; double LenOH, LenOB, LenHA = 0; double a = -1.0; double b = 2.0; LenOB = Math.Sqrt(vecOB[0] * vecOB[0] + vecOB[1] * vecOB[1] + vecOB[2] * vecOB[2]); pictOut = new Bitmap(this.w, this.h); for (int i = 0; i < this.w; i++) { for (int j = 0; j < this.h; j++) { LenHA = 0; C1 = pictIn.GetPixel(i, j); vecOA[0] = C1.R - vecCen[0]; vecOA[1] = C1.G - vecCen[1]; vecOA[2] = C1.B - vecCen[2]; LenOH = (vecOA[0] * vecOB[0] + vecOA[1] * vecOB[1] + vecOA[2] * vecOB[2]) / LenOB; for (int k = 0; k < 3; k++) { vecOH[k] = LenOH / LenOB * vecOB[k]; vecHA[k] = -vecOH[k] + vecOA[k]; LenHA += vecHA[k] * vecHA[k]; } LenHA = Math.Sqrt(LenHA); r1 = LenHA / 255; r2 = (a * r1 + b); for (int k = 0; k < 3; k++) { //vecOA2[k] = cutNum(0,255,(int)( r2 * vecHA[k] + vecOH[k]+vecCen[k])); vecOA2[k] = cutNum(0, 255, (int)(r2 * vecHA[k] * 0 + vecOH[k] + vecCen[k])); } pictOut.SetPixel(i, j, Color.FromArgb( (int)vecOA2[0], (int)vecOA2[1], (int)vecOA2[2])); } } return pictOut; } public Bitmap flatFilter(Bitmap pictIn) { //テンプレ Color C1; this.h = pictIn.Height; this.w = pictIn.Width; int rgbR, rgbG, rgbB; pictOut = new Bitmap(this.w, this.h); for (int i = 0; i < this.w; i++) { for (int j = 0; j < this.h; j++) { C1 = pictIn.GetPixel(i, j); if (C1.R + C1.G + C1.B > 255) { rgbR = (int)(C1.R * 0.5 + 255 * 0.5); rgbG = (int)(C1.G * 0.5 + 255 * 0.5); rgbB = (int)(C1.B * 0.5 + 255 * 0.5); } else { rgbR = (int)(C1.R * 0.5); rgbG = (int)(C1.G * 0.5); rgbB = (int)(C1.B * 0.5); } pictOut.SetPixel(i, j, Color.FromArgb(rgbR, rgbG, rgbB)); } } return pictOut; } private int cutNum(int min, int max, int t) { if (t < min) { t = min; } if (t > max) { t = max; } return t; } } public class pict_RGB_And_Deviation { public double aveR, aveG, aveB; public double devR, devG, devB; public pict_RGB_And_Deviation(double inAveR, double inAveG, double inAveB, double inDevR, double inDevG, double inDevB) { aveR = inAveR; aveG = inAveG; aveB = inAveB; devR = inDevR; devG = inDevG; devB = inDevB; } public pict_RGB_And_Deviation(Bitmap b1) { Color C1; double countPictSize; for (int i = 0; i < b1.Width; i++) { for (int j = 0; j < b1.Height; j++) { C1 = b1.GetPixel(i, j); aveR += (double)C1.R; aveG += (double)C1.G; aveB += (double)C1.B; } } countPictSize = b1.Width * b1.Height; aveR /= countPictSize; aveG /= countPictSize; aveB /= countPictSize; for (int i = 0; i < b1.Width; i++) { for (int j = 0; j < b1.Height; j++) { C1 = b1.GetPixel(i, j); devR += ((double)C1.R - aveR) * ((double)C1.R - aveR); devG += ((double)C1.G - aveG) * ((double)C1.G - aveG); devB += ((double)C1.B - aveB) * ((double)C1.B - aveB); } } if (countPictSize > 1) { countPictSize--; } else { countPictSize = 1; } devR = Math.Sqrt(devR / countPictSize); devG = Math.Sqrt(devG / countPictSize); devB = Math.Sqrt(devB / countPictSize); } } public class cell { 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 Color aveColor() { if (count > 0) { return Color.FromArgb( (int)sumR/count, (int)sumG/count, (int)sumB/count) ; }else{ return (Color.FromArgb(0,0,0) ); } } } }

表示オプション

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