「小さなフィルタのサンプル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;
}
}
}