首页 > 代码库 > 图像处理---灰度处理(黑白效果)

图像处理---灰度处理(黑白效果)

转自:图像处理:黑白效果(灰度处理)

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的权值。
                当其权值取不同的值时,能够形成不同灰度的灰度图象,由于人眼对绿色的敏感度最高,红色次之,
                蓝色最低,因此当w> w> 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方法的实现参考柔化(平滑)处理
        使用不安全模式参考椒盐噪声(杂点) 方法一;
        本例实现方法与椒盐噪声(杂点)方法二相同。