zoukankan      html  css  js  c++  java
  • 图像处理---灰度处理(黑白效果)

    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方法的实现参考柔化(平滑)处理
            使用不安全模式参考椒盐噪声(杂点) 方法一;
            本例实现方法与椒盐噪声(杂点)方法二相同。

  • 相关阅读:
    理解inode
    贝叶斯公式与拼写检查器
    《C程序设计语言》第四章 函数和程序结构
    MIT《计算机科学与编程导论》课堂笔记
    很牛的牛顿迭代法
    开发一个小工具重温C#经典问题
    斯坦福《编程方法学》环境搭建及常见问题
    看Sybase官方手册学索引工作原理
    学习编程的方法、软件和工具
    大师里奇留给了我们什么
  • 原文地址:https://www.cnblogs.com/jameslong/p/3805993.html
Copyright © 2011-2022 走看看