📄 filters.cs
字号:
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace MyApp.Filters
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class filters //滤波函数类
{
private int[][] Average; //均值矩阵
private int[][] Sobel1; //Sobel算子矩阵
private int[][] Sobel2;
private int[][] Prewitt1; //Prewitt算子矩阵
private int[][] Prewitt2;
private int[][] Kirsch1; //Kirsch算子矩阵
private int[][] Kirsch2;
private int[][] Kirsch3;
private int[][] Kirsch4;
private int[][] Kirsch5;
private int[][] Kirsch6;
private int[][] Kirsch7;
private int[][] Kirsch8;
private int[][] Laplacian; //laplacian算子矩阵
private int[][] BitmapArray; //灰度矩阵
private int nWidth; //图宽
private int nHeight; //图高
private double sigma=0.36; //sigma系数
private int[][] dotlight;
public filters()
{
//以下是初始化各个算子矩阵
InitAverage();
InitSobel();
InitPrewitt();
InitKirsch();
InitLaplacian();
InitDotLight();
}
public void Bitmap2Array(Bitmap b) //位图转灰度矩阵
{
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite,b.PixelFormat);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
BitmapArray=new int[b.Height][];
unsafe //以下为不受管制的c#
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
nWidth = b.Width;
nHeight= b.Height;
for(int y=0;y<nHeight;y++)
{
BitmapArray[y]=new int[b.Width];
for(int x=0; x < nWidth; x++ )
{
BitmapArray[y][x]=p[0];
p += 3;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
}
public int[][] GetBitmapArray(Bitmap b) //同上
{
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite,b.PixelFormat);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
int[][] Array=new int[b.Height][];
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
nWidth = b.Width;
nHeight= b.Height;
for(int y=0;y<nHeight;y++)
{
Array[y]=new int[b.Width];
for(int x=0; x < nWidth; x++ )
{
Array[y][x]=p[0];
p += 3;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
return Array;
}
private double[][] GetArray(Bitmap myBitmap) //同上
{
int height=myBitmap.Height;
int width=myBitmap.Width;
double[][] array=new double[height][];
int i,j;
for(i=0;i<=height-1;i++)
{
array[i]=new double[width];
for(j=0;j<=width-1;j++)
{
array[i][j]=myBitmap.GetPixel(j,i).R;
}
}
return array;
}
private void GetMatch(double[][] array1,double[][] array2) //算出匹配矩阵
{
//double temp1=(double[][])array1.Clone();
//double temp2=(double[][])array2.Clone();
}
public double GetError(Bitmap myBitmap1,Bitmap myBitmap2) //算均方差
{
double[][] array1=GetArray(myBitmap1);
double[][] array2=GetArray(myBitmap2);
GetMatch(array1,array2);
double re=0;
for(int i=0;i<=array1.Length-1;i++)
for(int j=0;j<=array1[0].Length-1;j++)
{
re+=Math.Pow((array1[i][j]-array2[i][j]),2);
}
re=re/(array1.Length*array1[0].Length);
re=Math.Sqrt(re);
return re;
}
private void InitDotLight()
{
dotlight=new int[5][];
dotlight[0]=new int[5];
dotlight[0][0]=0;
dotlight[0][1]=1;
dotlight[0][2]=2;
dotlight[0][3]=1;
dotlight[0][4]=0;
dotlight[1]=new int[5];
dotlight[1][0]=1;
dotlight[1][1]=4;
dotlight[1][2]=8;
dotlight[1][3]=4;
dotlight[1][4]=1;
dotlight[2]=new int[5];
dotlight[2][0]=2;
dotlight[2][1]=8;
dotlight[2][2]=16;
dotlight[2][3]=8;
dotlight[2][4]=2;
dotlight[3]=new int[5];
dotlight[3][0]=1;
dotlight[3][1]=4;
dotlight[3][2]=8;
dotlight[3][3]=4;
dotlight[3][4]=1;
dotlight[4]=new int[5];
dotlight[4][0]=0;
dotlight[4][1]=1;
dotlight[4][2]=2;
dotlight[4][3]=1;
dotlight[4][4]=0;
}
private void InitLaplacian()
{
Laplacian=new int[3][];
Laplacian[0]=new int[3];
Laplacian[0][0]=1;
Laplacian[0][1]=1;
Laplacian[0][2]=1;
Laplacian[1]=new int[3];
Laplacian[1][0]=1;
Laplacian[1][1]=-8;
Laplacian[1][2]=1;
Laplacian[2]=new int[3];
Laplacian[2][0]=1;
Laplacian[2][1]=1;
Laplacian[2][2]=1;
}
private void InitAverage()
{
Average=new int[3][];
for(int i=0;i<=2;i++)
{
Average[i]=new int[3];
for(int j=0;j<=2;j++)
{
Average[i][j]=1;
}
}
}
private void InitKirsch()
{
Kirsch1=new int[3][];
Kirsch1[0]=new int[3];
Kirsch1[0][0]=5;
Kirsch1[0][1]=5;
Kirsch1[0][2]=5;
Kirsch1[1]=new int[3];
Kirsch1[1][0]=-3;
Kirsch1[1][1]=0;
Kirsch1[1][2]=-3;
Kirsch1[2]=new int[3];
Kirsch1[2][0]=-3;
Kirsch1[2][1]=-3;
Kirsch1[2][2]=-3;
Kirsch2=new int[3][];
Kirsch2[0]=new int[3];
Kirsch2[0][0]=-3;
Kirsch2[0][1]=5;
Kirsch2[0][2]=5;
Kirsch2[1]=new int[3];
Kirsch2[1][0]=-3;
Kirsch2[1][1]=0;
Kirsch2[1][2]=5;
Kirsch2[2]=new int[3];
Kirsch2[2][0]=-3;
Kirsch2[2][1]=-3;
Kirsch2[2][2]=-3;
Kirsch3=new int[3][];
Kirsch3[0]=new int[3];
Kirsch3[0][0]=-3;
Kirsch3[0][1]=-3;
Kirsch3[0][2]=5;
Kirsch3[1]=new int[3];
Kirsch3[1][0]=-3;
Kirsch3[1][1]=0;
Kirsch3[1][2]=5;
Kirsch3[2]=new int[3];
Kirsch3[2][0]=-3;
Kirsch3[2][1]=-3;
Kirsch3[2][2]=5;
Kirsch4=new int[3][];
Kirsch4[0]=new int[3];
Kirsch4[0][0]=-3;
Kirsch4[0][1]=-3;
Kirsch4[0][2]=-3;
Kirsch4[1]=new int[3];
Kirsch4[1][0]=-3;
Kirsch4[1][1]=0;
Kirsch4[1][2]=5;
Kirsch4[2]=new int[3];
Kirsch4[2][0]=-3;
Kirsch4[2][1]=5;
Kirsch4[2][2]=5;
Kirsch5=new int[3][];
Kirsch5[0]=new int[3];
Kirsch5[0][0]=-3;
Kirsch5[0][1]=-3;
Kirsch5[0][2]=-3;
Kirsch5[1]=new int[3];
Kirsch5[1][0]=-3;
Kirsch5[1][1]=0;
Kirsch5[1][2]=-3;
Kirsch5[2]=new int[3];
Kirsch5[2][0]=5;
Kirsch5[2][1]=5;
Kirsch5[2][2]=5;
Kirsch6=new int[3][];
Kirsch6[0]=new int[3];
Kirsch6[0][0]=-3;
Kirsch6[0][1]=-3;
Kirsch6[0][2]=-3;
Kirsch6[1]=new int[3];
Kirsch6[1][0]=5;
Kirsch6[1][1]=0;
Kirsch6[1][2]=-3;
Kirsch6[2]=new int[3];
Kirsch6[2][0]=5;
Kirsch6[2][1]=5;
Kirsch6[2][2]=-3;
Kirsch7=new int[3][];
Kirsch7[0]=new int[3];
Kirsch7[0][0]=5;
Kirsch7[0][1]=-3;
Kirsch7[0][2]=-3;
Kirsch7[1]=new int[3];
Kirsch7[1][0]=5;
Kirsch7[1][1]=0;
Kirsch7[1][2]=-3;
Kirsch7[2]=new int[3];
Kirsch7[2][0]=5;
Kirsch7[2][1]=-3;
Kirsch7[2][2]=-3;
Kirsch8=new int[3][];
Kirsch8[0]=new int[3];
Kirsch8[0][0]=5;
Kirsch8[0][1]=5;
Kirsch8[0][2]=-3;
Kirsch8[1]=new int[3];
Kirsch8[1][0]=5;
Kirsch8[1][1]=0;
Kirsch8[1][2]=-3;
Kirsch8[2]=new int[3];
Kirsch8[2][0]=-3;
Kirsch8[2][1]=-3;
Kirsch8[2][2]=-3;
}
private void InitSobel()
{
Sobel1=new int[3][];
Sobel1[0]=new int[3];
Sobel1[0][0]=-1;
Sobel1[0][1]=0;
Sobel1[0][2]=1;
Sobel1[1]=new int[3];
Sobel1[1][0]=-2;
Sobel1[1][1]=0;
Sobel1[1][2]=2;
Sobel1[2]=new int[3];
Sobel1[2][0]=-1;
Sobel1[2][1]=0;
Sobel1[2][2]=1;
Sobel2=new int[3][];
Sobel2[0]=new int[3];
Sobel2[0][0]=-1;
Sobel2[0][1]=-2;
Sobel2[0][2]=-1;
Sobel2[1]=new int[3];
Sobel2[1][0]=0;
Sobel2[1][1]=0;
Sobel2[1][2]=0;
Sobel2[2]=new int[3];
Sobel2[2][0]=1;
Sobel2[2][1]=2;
Sobel2[2][2]=1;
}
private void InitPrewitt()
{
Prewitt1=new int[3][];
Prewitt1[0]=new int[3];
Prewitt1[0][0]=-1;
Prewitt1[0][1]=-1;
Prewitt1[0][2]=-1;
Prewitt1[1]=new int[3];
Prewitt1[1][0]=0;
Prewitt1[1][1]=0;
Prewitt1[1][2]=0;
Prewitt1[2]=new int[3];
Prewitt1[2][0]=1;
Prewitt1[2][1]=1;
Prewitt1[2][2]=1;
Prewitt2=new int[3][];
Prewitt2[0]=new int[3];
Prewitt2[0][0]=-1;
Prewitt2[0][1]=0;
Prewitt2[0][2]=1;
Prewitt2[1]=new int[3];
Prewitt2[1][0]=-1;
Prewitt2[1][1]=0;
Prewitt2[1][2]=1;
Prewitt2[2]=new int[3];
Prewitt2[2][0]=-1;
Prewitt2[2][1]=0;
Prewitt2[2][2]=1;
}
private void MySetPixel(int x,int y,Bitmap b,byte color) //写像素
{
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite,b.PixelFormat);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
nWidth = b.Width;
nHeight= b.Height;
p+=(nOffset+nWidth*3)*(y-1)+(x-1)*3;
p[0]=color;
p[1]=color;
p[2]=color;
}
b.UnlockBits(bmData);
}
private byte MyGetPixel(int x,int y,Bitmap b) //取像素
{
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite,b.PixelFormat);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
byte re;
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
nWidth = b.Width;
nHeight= b.Height;
p+=(nOffset+nWidth*3)*(y-1)+(x-1)*3;
re=p[0];
}
b.UnlockBits(bmData);
return re;
}
private int[][] BlearArray(Bitmap myBitmap,int width,int height)
{
int[][] array=new int[5][];
for(int i=0;i<=4;i++)
{
array[i]=new int[5];
for(int j=0;j<=4;j++)
{
if(width-2+i>=0&&width-2+i<=myBitmap.Width-1&&height-2+j>=0&&height-2+j<=myBitmap.Height-1)
array[i][j]=myBitmap.GetPixel(width-2+i,height-2+j).R;
else array[i][j]=999;
}
}
return array;
}
private void DotLightPixel(Bitmap myBitmap,int width,int height,int[][] array) //均值窗
{
int sum=0;
int flag=0;
for(int i=0;i<=4;i++)
for(int j=0;j<=4;j++)
{
if(array[i][j]!=999)
{
sum+=dotlight[i][j]*array[i][j];
}
else
{
flag=1;
}
}
sum=sum/80;
if(flag==1) sum=array[2][2];
else if(sum>255) sum=255;
else if(sum<0) sum=0;
myBitmap.SetPixel(width,height,Color.FromArgb(sum,sum,sum));
}
public Bitmap Filter_Blear(Bitmap myBitmap) //alpha修饰滤波
{
int width=myBitmap.Width;
int height=myBitmap.Height;
Bitmap clone=new Bitmap(width,height);
for(int i=0;i<=height-1;i++)
for(int j=0;j<=width-1;j++)
DotLightPixel(clone,j,i,BlearArray(myBitmap,j,i));
return clone;
}
private double[][] BlearArray(double[][] array1,int width,int height)
{
double[][] array=new double[5][];
for(int i=0;i<=4;i++)
{
array[i]=new double[5];
for(int j=0;j<=4;j++)
{
if(width-2+i>=0&&width-2+i<=array1[0].Length-1&&height-2+j>=0&&height-2+j<=array1.Length-1)
array[i][j]=array1[height-2+j][width-2+i];
else array[i][j]=999;
}
}
return array;
}
public Bitmap Iterate(Bitmap myBitmap,double lamda,int c)
{
double[][] array_g=GetArray(myBitmap);
int flag=0;
double[][] array_f=NumMulArray(array_g,lamda);
int cc=0;
double tempError=0;
while(flag==0)
{
double[][] temp_f=GetClone(array_f);
for(int i=0;i<temp_f.Length;i++)
for(int j=0;j<temp_f[0].Length;j++)
{
array_f[i][j]=temp_f[i][j]+lamda*(array_g[i][j]-conv(BlearArray(temp_f,j,i)));
}
//flag=Condition(epthilon,array_g,array_f,lamda);
double error=Condition(array_f,temp_f);
//if(Math.Abs(tempError-error)/tempError<0.5&&lamda>0.1) lamda=lamda/2;
if(Math.Abs(tempError-error)/tempError<0.5) lamda=lamda/2;
tempError=error;
cc++;
if(cc==c) break;
}
Bitmap b=Array2Bitmap(array_f);
return b;
}
private double[][] GetClone(double[][] array)
{
double[][] re=new double[array.Length][];
for(int i=0;i<=re.Length-1;i++)
{
re[i]=new double[array[i].Length];
for(int j=0;j<re[i].Length;j++)
re[i][j]=array[i][j];
}
return re;
}
private Bitmap Array2Bitmap(double[][] array)
{
Bitmap b=new Bitmap(array[0].Length,array.Length);
for(int i=0;i<array.Length;i++)
for(int j=0;j<array[0].Length;j++)
{
int cl=(int)array[i][j];
if(cl>255) cl=255;
if(cl<0) cl=0;
b.SetPixel(j,i,Color.FromArgb(cl,cl,cl));
}
return b;
}
private double Condition(double[][] temp_f,double[][] array_f)
{
int flag=0;
double sum=0;
for(int i=0;i<array_f.Length;i++)
for(int j=0;j<array_f[0].Length;j++)
{
sum+=Math.Pow(array_f[i][j]-temp_f[i][j],2);
}
return sum;
}
private double conv(double[][] array)
{
double sum=0;
int flag=0;
for(int i=0;i<=4;i++)
for(int j=0;j<=4;j++)
{
if(array[i][j]!=999)
{
sum+=(double)dotlight[i][j]*array[i][j];
}
else
{
flag=1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -