📄 ps 1 new.txt
字号:
struct ARGB
//定义ARGB结构体
{
public byte A;
public byte R;
public byte G;
public byte B;
public ARGB(byte A,byte R,byte G,byte B)
{
this.A = A;
this.R = R;
this.G = G;
this.B = B;
}
}
void main()
{
double RR=0,BB=0, GG=0;
float [,] mask1 = new float[5,5];//均值滤波模板
for (int m=0;m<mask1.GetLength(0);m++)//模板赋值
for (int n=0;n<mask1.GetLength(1);n++)
{
mask1[m,n] = 1.0f/25;//模板像素各值取为1.0.
}
ARGB[,] CImg=LoadColorImg();//载入ARGB彩色图片。
if(CImg==null) return;
ShowImg("",CImg);
int w = CImg.GetLength(0);
int h = CImg.GetLength(1);
ARGB [,] Img = new ARGB[w,h]; //新键一幅ARGB彩色图片
ARGB [,] Img_pinghua_filter = new ARGB[w,h];//存放平滑后的CIMG图象。
ARGB [,] CImgpinghuafilter = new ARGB [w,h];
byte [,] ImgIpinghuafilter = new byte [w,h];
ARGB [,] ImgH = new ARGB[w,h]; //新键一幅ARGB彩色图片,用于显示H分量
ARGB [,] ImgS = new ARGB[w,h]; //新键一幅ARGB彩色图片,用于显示S分量
byte [,] ImgI = new byte[w,h]; //新键一幅ARGB彩色图片,用于显示I分量
ARGB [,] ImgRGB = new ARGB[w,h];
int nHValue,nSValue,nIValue; //定义代表H,S,I三个整型变量。
for (int y=0;y<h;y++)
for ( int x=0;x<w;x++)
{
float R = ((float) CImg[x,y].R) / 255;//将R,G,B三个分量归一化
float G = ((float) CImg[x,y].G) / 255;
float B = ((float) CImg[x,y].B) / 255;
float max_value_of_rgb = max(R,G,B);//取R,G,B中大的值
float min_value_of_rgb = min(R,G,B);//取R,G,B中小的值
float fSumRGB = R + G + B;
float I = ( R + G + B) / 3;
double S = 1.0 - 3.0 * min_value_of_rgb / fSumRGB;
double H = Math.Acos( (( R - G ) + ( R - B ))/(2 *( Sqrt( ( R - G )*( R - G ) + ( R -B ) * ( G - B)))));
if( CImg[x,y].R == CImg[x,y].G && CImg[x,y].G == CImg[x,y].B )
{
nHValue = 0;
nSValue = 0;
nIValue = (CImg[x,y].R)/ 255 * 100;
}
double fHAngle = H /3.1415927 * 180;
if( G < B )
fHAngle = 360 - fHAngle;
if( fHAngle > 360.0 )
fHAngle = 360.0;
nHValue = (byte) (fHAngle / 360 * 255);
nSValue =(byte) (S * 100);
nIValue = (byte) (I * 100);
if(fHAngle>=0&&fHAngle<120)//显示H分量
ImgH[x,y]=new ARGB(255,(byte)(255*(1-fHAngle/120)),(byte)(255*fHAngle/120),0);
if(fHAngle>=120&&fHAngle<240)
ImgH[x,y]=new ARGB(255,0,(byte)(255-(fHAngle-120)/120*255),(byte)((fHAngle-120)/120*255));
if(fHAngle>=240&&fHAngle<360)
ImgH[x,y]=new ARGB(255,(byte)((fHAngle-240)/120*255),0,(byte)(255-(fHAngle-240)/120*255));
ImgS[x,y]=new ARGB(255,(byte)(S*255),(byte)(S*255),(byte)(S*255));//显示S分量
ImgI[x,y]=(byte)(I*255);//显示I分量
//以下是在上面的基础上HSI转换为RGB.
double fHAngle1 = ((float)nHValue)/255*360;
double H1 = fHAngle/180*3.14;
double S1 = S;
double I1 = I;
if(fHAngle1>=0&&fHAngle1<120)
{
BB=I1*(1.0-S1);
RR=I1*(1.0+(S1*Cos(H1)/Cos(60.0/180*3.14-H1)));
GG=3.0*I1-(BB + RR);
}
else if(fHAngle1>=120&&fHAngle1<240 )
{
RR=I1*(1.0-S1);
GG=I1*(1.0+S1*Cos(H1-120.0/180*3.14)/Cos(180.0/180*3.14-H1));
BB=3.0*I-(RR+GG);
}
else if(fHAngle1>=240&&fHAngle1<360 )
{
GG = I1*( 1.0-S1 );
BB = I1*( 1.0+S1*Cos(H1-240.0/180*3.14)/Cos(300.0/180*3.14-H1));
RR = 3.0*I1-( GG + BB );
}
if (nSValue==0)
{
RR=GG=BB=I1;
}
int r =(int)(RR * 255);
if(r>255) r=255;
if (r<0) r = 0;
int R_value_in_rgb=(byte)r;
int g =(int)(GG * 255);
if(g>255) g=255;
if (g<0) g=0;
int G_value_in_rgb=(byte)g;
int b =(int)(BB * 255);
if(b>255) b=255;
if (b<0) b=0;
int B_value_in_rgb=(byte)b;
ImgRGB[x,y]=new ARGB(255,(byte)R_value_in_rgb,(byte)G_value_in_rgb,(byte)B_value_in_rgb);
}//第一个大的FOR循环结束
//以下是对IMGI进行均值平滑滤波;
for (int y=2;y<h-2;y++)
for (int x=2;x<w-2;x++)
{
double r1=0;
for (int m=-2;m<=2;m++)
for (int n=-2;n<=2;n++)
{
r1+=ImgI[x+m,y+n]*mask1[2+m,2+n];//像素与模板相乘再累加。
}
r1=1.10*r1;//对I进行略微的增强。
if (r1>255) r1 = 255;//将灰度归置到0—255范围内。
if (r1<0) r1 = 0;
ImgIpinghuafilter[x,y]=(byte)r1;
}//以上是对IMGI进行均值滤波。
//以下再将平滑后的I分量反变化回RGB图象
for (int y=0;y<h;y++)
for ( int x=0;x<w;x++)
{
float R = ((float) CImg[x,y].R) / 255;//将R,G,B三个分量归一化
float G = ((float) CImg[x,y].G) / 255;
float B = ((float) CImg[x,y].B) / 255;
float max_value_of_rgb = max(R,G,B);//取R,G,B中大的值
float min_value_of_rgb = min(R,G,B);//取R,G,B中小的值
float fSumRGB = R + G + B;
float I = ( R + G + B) / 3;
double S = 1.0 - 3.0 * min_value_of_rgb / fSumRGB;
double H = Math.Acos( (( R - G ) + ( R - B ))/(2 *( Sqrt( ( R - G )*( R - G ) + ( R -B ) * ( G - B)))));
if( CImg[x,y].R == CImg[x,y].G && CImg[x,y].G == CImg[x,y].B )
{
nHValue = 0;
nSValue = 0;
nIValue = (CImg[x,y].R)/ 255 * 100;
}
double fHAngle = H /3.1415927 * 180;
if( G < B )
fHAngle = 360 - fHAngle;
if( fHAngle > 360.0 )
fHAngle = 360.0;
nHValue = (byte) (fHAngle / 360 * 255);
nSValue =(byte) (S * 100);
nIValue = (byte) (I * 100);
//以下是在上面的基础上HSI转换为RGB.
double fHAngle1 = ((float)nHValue)/255*360;
double H1 = fHAngle/180*3.14;
double S1 = S;
double I1 = ImgIpinghuafilter[x,y]/255.0;//I1 用对I分量平滑后的值代替。
if(fHAngle1>=0&&fHAngle1<120)
{
BB=I1*(1.0-S1);
RR=I1*(1.0+(S1*Cos(H1)/Cos(60.0/180*3.14-H1)));
GG=3.0*I1-(BB + RR);
}
else if(fHAngle1>=120&&fHAngle1<240 )
{
RR=I1*(1.0-S1);
GG=I1*(1.0+S1*Cos(H1-120.0/180*3.14)/Cos(180.0/180*3.14-H1));
BB=3.0*I-(RR+GG);
}
else if(fHAngle1>=240&&fHAngle1<360 )
{
GG = I1*( 1.0-S1 );
BB = I1*( 1.0+S1*Cos(H1-240.0/180*3.14)/Cos(300.0/180*3.14-H1));
RR = 3.0*I1-( GG + BB );
}
if (nSValue==0)
{
RR=GG=BB=I1;
}
int r =(int)(RR * 255);
if(r>255) r=255;
if (r<0) r = 0;
int R_value_in_rgb=(byte)r;
int g =(int)(GG * 255);
if(g>255) g=255;
if (g<0) g=0;
int G_value_in_rgb=(byte)g;
int b =(int)(BB * 255);
if(b>255) b=255;
if (b<0) b=0;
int B_value_in_rgb=(byte)b;
Img_pinghua_filter[x,y]=new ARGB(255,(byte)R_value_in_rgb,(byte)G_value_in_rgb,(byte)B_value_in_rgb);
//以上是再将平滑后的I分量反变化回RGB图象
}//第二个大的FOR循环结束。
//以下是对IMG的I进行SOBEL算子边缘检测。
float [,] Gy = new float [w,h];
float [,] Gx = new float [w,h];
double [,] angletan = new double [w,h];
byte [] A = new byte [9];//数组A大小为下面模板MASK大小;
byte [,]Ifilter= new byte[w,h];
byte [,] mask = new byte [3,3];// sobel filter模板大小为3*3
int M = mask.GetLength(0)/2;
int N = mask.GetLength(1)/2;
for (int y=N;y<h-N;y++)
for (int x=M;x<w-M;x++)
{
double r=0;
A[0]=ImgIpinghuafilter[x,y];
A[1]=ImgIpinghuafilter[x-1,y];
A[2]=ImgIpinghuafilter[x,y+1];
A[3]=ImgIpinghuafilter[x,y-1];
A[4]=ImgIpinghuafilter[x+1,y];
A[5]=ImgIpinghuafilter[x+1,y-1];
A[6]=ImgIpinghuafilter[x+1,y+1];
A[7]=ImgIpinghuafilter[x-1,y+1];
A[8]=ImgIpinghuafilter[x-1,y-1];
r= Abs((A[6]+2*A[2]+A[7])-(2*A[3]+A[5]+A[8])+(A[8]+2*A[1]+A[7])-(A[6]+2*A[4]+A[5]));//SOBEL算子算法。
if (r>255) r = 255;
if (r<0) r = 0;
Ifilter[x,y] = (byte)r;
Gy[x,y]=A[8]+2*A[3]+A[5]-A[7]-2*A[2]-A[6];//垂直方向算子;
Gx[x,y]=(A[6]+2*A[4]+A[5])-(A[8]+2*A[1]+A[7]);//水平方向SOBEL算子;
angletan[x,y]=Math.Atan2(Gy[x,y],Gx[x,y]);//求剃度角
}//以上是对IMG的I进行SOBEL算子边缘检测。
//以下是选择出边缘点并加以绘制
ARGB [,] Img_pinghua_filter_draw = new ARGB[w,h];//新建一副RGB图象,存放绘制边缘后的图象。
for (int y=0;y<h;y++)
for ( int x=0;x<w;x++)
{
//Img_pinghua_filter[x,y].G=(byte)(Img_pinghua_filter[x,y].G*1.5);
Img_pinghua_filter_draw[x,y]=new ARGB(255,Img_pinghua_filter[x,y].R,Img_pinghua_filter[x,y].G,Img_pinghua_filter[x,y].B);
if(Ifilter[x,y]>=25)//将把SOBEL算子检测后的I分量中大于25(可以改变)的值颜色变淡。
{
double rrr1=0,rrr2=0,rrr3=0;
rrr1=Img_pinghua_filter[x,y].R*0.55;//0.55可以改变
Img_pinghua_filter_draw[x,y].R=(byte)rrr1;
rrr2=Img_pinghua_filter[x,y].G*0.55;
Img_pinghua_filter_draw[x,y].G=(byte)rrr2;
rrr3=Img_pinghua_filter[x,y].B*0.55;
Img_pinghua_filter_draw[x,y].B=(byte)rrr3;
Img_pinghua_filter_draw[x,y]=new ARGB(255,Img_pinghua_filter_draw[x,y].R,Img_pinghua_filter_draw[x,y].G,Img_pinghua_filter_draw[x,y].B);
}
}
ARGB [,] Img_pinghua_filter_drawline = new ARGB[w,h];
int xx=0,yy=0;
for (int y=0;y<h;y++)
for ( int x=0;x<w;x++)
{
for(int rrr=0;rrr<10;rrr++)//线条长度为10个像素;
{
Img_pinghua_filter_drawline[x,y]=new ARGB(255,Img_pinghua_filter_draw[x,y].R,Img_pinghua_filter_draw[x,y].G,Img_pinghua_filter_draw[x,y].B);
if(Ifilter[x,y]>=25)//对于边缘检测后的I分量中大于100的值加以绘制。
{
xx=(int)(x+rrr*Math.Cos(angletan[x,y]+1.571));
yy=(int)(y-rrr*Math.Sin(angletan[x,y]+1.571));
//Img_pinghua_filter_draw[xx,yy].R=(byte)(Img_pinghua_filter_draw[x,y].R*0.6);
//Img_pinghua_filter_draw[xx,yy].G=(byte)(Img_pinghua_filter_draw[x,y].G*0.6);
//Img_pinghua_filter_draw[xx,yy].B=(byte)(Img_pinghua_filter_draw[x,y].B*0.6);
if(xx>0&&xx<w&&yy>0&&yy<h)//防止线条越界。
Img_pinghua_filter_drawline[xx,yy]=new ARGB(255,0,0,0);
//new ARGB(255,Img_pinghua_filter_draw[x,y].R,Img_pinghua_filter_draw[x,y].G,Img_pinghua_filter_draw[x,y].B);
}
}
}
//以上是选择出边缘点并加以绘制
//ShowImg("H",ImgH);
//ShowImg("S",ImgS);
//ShowImg("I",ImgI);
//ShowImg("HSI-RGB",ImgRGB);
//ShowImg("Ifilter",Ifilter);
//ShowImg("ImgIpinghuafilter",ImgIpinghuafilter);
ShowImg("Img_pinghua_filter",Img_pinghua_filter);
ShowImg("Img_pinghua_filter_draw",Img_pinghua_filter_draw);
ShowImg("Img_pinghua_filter_drawline",Img_pinghua_filter_drawline);
}//MAIN函数结束
float max(float R,float G,float B)//MAX函数
{
if(R-G>0&&R-B>0)
return R;
if(G-R>0&&G-B>0)
return G;
else return B;
}
float min(float R,float G,float B)//MIN函数
{
if(R-G<0&&R-B<0)
return R;
if(G-R<0&&G-B<0)
return G;
else return B;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -