1.效果图:
2.实现原理:
图像灰度化就是使色彩的三种颜色分量R、G、B的值相同,由于颜色值的取值范围是[0,255],所以灰度的
级别只有256种,即灰度图象仅能表现256种灰度颜色,常用有3种处理方法:
*最大值法(Maximum):R=G=B=Max(R,G,B),这种方法处理后灰度图象的亮度会偏高。
*平均值法(Average):R=G=B=(R+G+B)/3,这种方法处理后灰度图象的亮度较柔和。
*加权平均值法(Weighted Average):
R=G=B=wr*R+wg*G+wb*B,wr、wg、wb分别为R、G、B的权值。
当其权值取不同的值时,能够形成不同灰度的灰度图象,由于人眼对绿色的敏感度最高,红色次之,
蓝色最低,因此当wg > wr > wb时,所产生的灰度图像更符合人眼的视觉感受。
通常wr=30%,wg=59%,wb=11%,图像的灰度最合理。
以下的程序使用的是wr=70%,wg=20%,wb=10%觉得效果更好。
3.实现代码:
枚举三种算法
1public enum AlgorithmsType
2 {
3 MaxValue, //最大值法
4 AverageValue, //平均值法
5 WeightAverage //加权平均值法
6 }
具体实现
public static Image Gray(Image img, AlgorithmsType algo)
{
int width = img.Width;
int height = img.Height;
Bitmap bmp = new Bitmap(img);
//设定实例BitmapData相关信息
Rectangle rect = new Rectangle(0, 0, width, height);
ImageLockMode mode = ImageLockMode.ReadWrite;
PixelFormat format = PixelFormat.Format32bppArgb;
//锁定bmp到系统内存中
BitmapData data = bmp.LockBits(rect, mode, format);
//获取位图中第一个像素数据的地址
IntPtr ptr = data.Scan0;
int numBytes = width * height * 4;
byte[] rgbValues = new byte[numBytes];
//将bmp数据Copy到申明的数组中
Marshal.Copy(ptr, rgbValues, 0, numBytes);
for (int i = 0; i < rgbValues.Length; i += 4)
{
int value = 0;
switch (algo)
{
//最大值法
case AlgorithmsType.MaxValue:
value = rgbValues[i] > rgbValues[i + 1] ? rgbValues[i] : rgbValues[i + 1];
value = value > rgbValues[i + 2] ? value : rgbValues[i + 2];
break;
//平均值法
case AlgorithmsType.AverageValue:
value = (int)((rgbValues[i] + rgbValues[i + 1] + rgbValues[i + 2]) / 3);
break;
//加权平均值法
case AlgorithmsType.WeightAverage:
value = (int)(rgbValues[i] * 0.1 + rgbValues[i + 1] * 0.2
+ rgbValues[i + 2] * 0.7);
break;
}
//将数组中存放R、G、B的值修改为计算后的值
for (int j = 0; j < 3; j++)
{
rgbValues[i + j] = (byte)value;
}
}
//将数据Copy到内存指针
Marshal.Copy(rgbValues, 0, ptr, numBytes);
//从系统内存解锁bmp
bmp.UnlockBits(data);
return (Image)bmp;
}
4.说明:
使用GetPixel方法和SetPixel方法的实现参考柔化(平滑)处理;
使用不安全模式参考椒盐噪声(杂点) 方法一;
本例实现方法与椒盐噪声(杂点)方法二相同。