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

小さなフィルタのサンプル1-2」(2010/06/10 (木) 16:23:05) の最新版変更点

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

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

[[小さなフィルタのサンプル]]をマルチスレッドにしてみた。 C#で人生初スレッド。 マルチスレッドは、デッドロックだの処理の排他的制御だの、現実に役に立つアプリやゲームアプリで絶対必須なので、これは大事なのだった。 実現したいものが複雑である以上、コードがそれに対応した複雑さになるのは当然の話だけど、マルチスレッドとか苦手。 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) { } private void button1_Click(object sender, EventArgs e) { Bitmap b1 = new Bitmap(pictureBox1.Image); // 変数の宣言 //pictureBox1.Image =b1; pictFilter PTC = new WindowsFormsApplication2.pictFilter(b1, new ExampleCallback(ResultCallback),pictureBox1); Thread t1 =new Thread(new ThreadStart(PTC.cercleChange)); t1.Start(); t1.Join(); //pictureBox1.Image = PTC.cercleChange(); // 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++; if (tc == 1) { pictureBox1.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/11161658_m.png"); } else if (tc == 2) { pictureBox1.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/11129096_m.jpg"); } else if (tc == 3) { pictureBox1.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/9933981.jpg"); } pictureBox1.Height = 1200; pictureBox1.Width = 1000; pictureBox1.Top = 0; pictureBox1.Left = 0; } } class pictFilter { Random rnd = new Random(); Bitmap pictOut = null; int h;//絵の高さ int w;//絵の横幅 Bitmap pictIn; ExampleCallback callback; PictureBox lastPict; public pictFilter(Bitmap b1, ExampleCallback callbackDelegate,PictureBox p1) { this.pictIn=b1; h = 0; w = 0; callback = callbackDelegate; lastPict = p1; } public Bitmap cercleChange2(Bitmap pictIn) { //各ピクセルの色空間内の位置を点(ccR,ccB,ccG)を中心に体積拡大する処理 float ccR = 118; float ccG = 118; float ccB = 118; float a = -1.0f; float b = 2.0f; double cR, cG, cB; double r1 = 0; double r2 = 0; Color CC,CU,CD,CR,CL; this.h = pictIn.Height; this.w = pictIn.Width; pictOut = new Bitmap(this.w, this.h); for (int i = 1; i < this.w-1; i++) { for (int j = 1; j < this.h-1; j++) { CC = pictIn.GetPixel(i, j); CU = pictIn.GetPixel(i, j-1); CD = pictIn.GetPixel(i, j + 1); CR = pictIn.GetPixel(i+1, j); CL = pictIn.GetPixel(i + 1, j); } } return pictOut; //テンプレ //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 = 118; float ccG = 118; float ccB = 118; float a=-1.0f; float b =2.0f; 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); 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))/225; 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 } } 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 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; vecOA[1] = C1.G; vecOA[2] = C1.B; 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.0; r2 = a * r1 + b; for (int k = 0; k < 3; k++) { vecOA2[k] = cutNum(0,255,(int)( r2 * vecHA[k] + vecOH[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; } } }
[[小さなフィルタのサンプル]]をマルチスレッドにしてみた。 C#で人生初スレッド。 マルチスレッドは、デッドロックだの処理の排他的制御だの複雑な話も増えるが、現実に役に立つアプリやゲームアプリで絶対必須なので、これは大事なのだった。 実現したいものが複雑である以上、コードがそれに対応した複雑さになるのは当然の話だけど、マルチスレッドとか苦手。 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) { } private void button1_Click(object sender, EventArgs e) { Bitmap b1 = new Bitmap(pictureBox1.Image); // 変数の宣言 //pictureBox1.Image =b1; pictFilter PTC = new WindowsFormsApplication2.pictFilter(b1, new ExampleCallback(ResultCallback),pictureBox1); Thread t1 =new Thread(new ThreadStart(PTC.cercleChange)); t1.Start(); t1.Join(); //pictureBox1.Image = PTC.cercleChange(); // 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++; if (tc == 1) { pictureBox1.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/11161658_m.png"); } else if (tc == 2) { pictureBox1.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/11129096_m.jpg"); } else if (tc == 3) { pictureBox1.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/9933981.jpg"); } pictureBox1.Height = 1200; pictureBox1.Width = 1000; pictureBox1.Top = 0; pictureBox1.Left = 0; } } class pictFilter { Random rnd = new Random(); Bitmap pictOut = null; int h;//絵の高さ int w;//絵の横幅 Bitmap pictIn; ExampleCallback callback; PictureBox lastPict; public pictFilter(Bitmap b1, ExampleCallback callbackDelegate,PictureBox p1) { this.pictIn=b1; h = 0; w = 0; callback = callbackDelegate; lastPict = p1; } public Bitmap cercleChange2(Bitmap pictIn) { //各ピクセルの色空間内の位置を点(ccR,ccB,ccG)を中心に体積拡大する処理 float ccR = 118; float ccG = 118; float ccB = 118; float a = -1.0f; float b = 2.0f; double cR, cG, cB; double r1 = 0; double r2 = 0; Color CC,CU,CD,CR,CL; this.h = pictIn.Height; this.w = pictIn.Width; pictOut = new Bitmap(this.w, this.h); for (int i = 1; i < this.w-1; i++) { for (int j = 1; j < this.h-1; j++) { CC = pictIn.GetPixel(i, j); CU = pictIn.GetPixel(i, j-1); CD = pictIn.GetPixel(i, j + 1); CR = pictIn.GetPixel(i+1, j); CL = pictIn.GetPixel(i + 1, j); } } return pictOut; //テンプレ //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 = 118; float ccG = 118; float ccB = 118; float a=-1.0f; float b =2.0f; 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); 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))/225; 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 } } 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 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; vecOA[1] = C1.G; vecOA[2] = C1.B; 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.0; r2 = a * r1 + b; for (int k = 0; k < 3; k++) { vecOA2[k] = cutNum(0,255,(int)( r2 * vecHA[k] + vecOH[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; } } }

表示オプション

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