c#中实现图片灰度化技术详解

去年买了本数字图像处理算法,一直都没有看,前几个星期都一直忙着工作上的活,趁这阶段悠闲点,玩一玩图片处理,这玩意还是非常有意思的。

以前我们在做Web上的用户注册时,通常都会做一个验证码,大家都知道用来防止暴力注册的,当然提到验证码大家都知道C#里面有一个Bitmap类专门用来处理图片的,好吧,这一篇我们从最简单的“图片灰度化”说起。

一:图片灰度化

我们都知道,位图是由一个一个像素点组成的,像素点可能是红色,橙色,粉色等等,这些颜色我们都知道是用RGB来表示的。

每个颜色分量都是一个字节(0-255),所以一般情况下图的像素点都是24位,当然还有32位,64位,当RGB是0-255之间的不同值时,那么该像素点就呈现“五颜六色”,而当RGB都是相同的值是,则像素点呈现“灰色”,如果大家玩过CSS的话,肯定都知道给一个字体的color通常都是#999999,#666666,#333333这些不同深度的灰色。

1.计算公式

下面我们该如何设置合理的灰度值呢?当然还是用当前的RGB为模板,然后对RGB乘以一个合理的权重就ok了

代码如下:

Gary(i,j)=0.299*R(i,j)+0.587*G(i,j)+0.114*B(i,j);

2.编程

有了公式,实现起来就不成问题了。Bitmap类中有一个GetPixel/SetPixel,它可以获取和设置当前的像素点。

static void Main(string[] args)
{
  Bitmap bitmap = new Bitmap(Environment.CurrentDirectory + "//1.jpg");

  for (int i = 0; i < bitmap.Width; i++)
  {
    for (int j = 0; j < bitmap.Height; j++)
    {
      //取图片当前的像素点
      var color = bitmap.GetPixel(i, j);

      var gray = (int)(color.R * 0.299 + color.G * 0.587 + color.B * 0.114);

      //重新设置当前的像素点
      bitmap.SetPixel(i, j, Color.FromArgb(gray, gray, gray));
    }
  }

  bitmap.Save(Environment.CurrentDirectory + "//2.jpg");
}

3.改进

上面这个方法很简单,Get/Set就Ok了,当然这是我们站在像素点这个角度来考虑问题的,貌似只要O(N2)的时间就可以KO问题,但是Get/Set远远不是O(1)的,基于性能考虑,我们能不能有更优的方法,此时我们可以站在字节这个角度思考,不过这里我们要注意一个问题就是:比如图片的width=21px,一个像素点占用3个字节,但是21个像素点不一定就占用63个字节,这是因为系统基于性能考虑,在每一行中存放着一个“未用区域”,来确保图片每行的byte数是4的倍数,那么如何去读某一行的字节数呢?

C#里面有一个Stride属性就可以用来获取,很简单吧。

static void Main(string[] args)
    {
      Bitmap bitmap = new Bitmap(Environment.CurrentDirectory + "//1.jpg");

      //定义锁定bitmap的rect的指定范围区域
      Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);

      //加锁区域像素
      var bitmapData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);

      //位图的首地址
      var ptr = bitmapData.Scan0;

      //stride:扫描行
      int len = bitmapData.Stride * bitmap.Height;

      var bytes = new byte[len];

      //锁定区域的像素值copy到byte数组中
      Marshal.Copy(ptr, bytes, 0, len);

      for (int i = 0; i < bitmap.Height; i++)
      {
        for (int j = 0; j < bitmap.Width * 3; j = j + 3)
        {
          var color = bytes[i * bitmapData.Stride + j + 2] * 0.299
                + bytes[i * bitmapData.Stride + j + 1] * 0.597
                + bytes[i * bitmapData.Stride + j] * 0.114;

          bytes[i * bitmapData.Stride + j]
               = bytes[i * bitmapData.Stride + j + 1]
               = bytes[i * bitmapData.Stride + j + 2] = (byte)color;
        }
      }

      //copy回位图
      Marshal.Copy(bytes, 0, ptr, len);

      //解锁
      bitmap.UnlockBits(bitmapData);

      bitmap.Save(Environment.CurrentDirectory + "//3.jpg");
    }

(0)

相关推荐

  • C#彩色图片灰度化算法实例

    本文实例讲述了C#彩色图片灰度化实现方法.分享给大家供大家参考.具体方法如下: 主要功能代码如下: 复制代码 代码如下: public static Bitmap MakeGrayscale(Bitmap original) { //create a blank bitmap the same size as original Bitmap newBitmap = new Bitmap(original.Width, original.Height); //get a graphics obje

  • C#实现把彩色图片灰度化代码分享

    彩色图片转为灰度图的公式如下: 复制代码 代码如下: gray(i,j) = 0.299 * Red(i,j)+0.587*Green(i,j)+0.114*Blue(i,j) 其中gray(i,j) 为转化后的灰度值  (i,j)为像素点的位置. 源代码如下: public static Bitmap ChangeGray(Bitmap b) { BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), Ima

  • 解析C#彩色图像灰度化算法的实现代码详解

    代码如下所示: 复制代码 代码如下: public static Bitmap MakeGrayscale(Bitmap original)        {            //create a blank bitmap the same size as original            Bitmap newBitmap = new Bitmap(original.Width, original.Height);            //get a graphics object

  • 基于c#图像灰度化、灰度反转、二值化的实现方法详解

    图像灰度化:将彩色图像转化成为灰度图像的过程成为图像的灰度化处理.彩色图像中的每个像素的颜色有R.G.B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围.而灰度图像是R.G.B三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图像以使后续的图像的计算量变得少一些.灰度图像的描述与彩色图像一样仍然反映了整幅图像的整体和局部的色度和亮度等级的分布和特征.图像的灰度

  • C#灰度化图像的实例代码

    用伪语句可以表示如下 public bitmap GrayScal(bitmap orgbmp){    建立一个与原图片等大的8位的图片    取出原图像中的每一个点    新图像的点=原图像点的红色量*系数1+绿色量*系数2+黄色量*系统3    返回新图像} 复制代码 代码如下: /// <summary>    /// 对图像进行点运算,    /// </summary>    public class PointTrans    {        private rea

  • C#数字图象处理之图像灰度化方法

    本文实例讲述了C#数字图象处理之图像灰度化方法.分享给大家供大家参考.具体如下: //定义图像灰度化函数 private static Bitmap PGray(Bitmap src) { int w = src.Width; int h = src.Height; //构建与原图像大小一样的模版图像 Bitmap dstBitmap = new Bitmap(src.Width, src.Height, System.Drawing.Imaging.PixelFormat.Format24bp

  • c#中实现图片灰度化技术详解

    去年买了本数字图像处理算法,一直都没有看,前几个星期都一直忙着工作上的活,趁这阶段悠闲点,玩一玩图片处理,这玩意还是非常有意思的. 以前我们在做Web上的用户注册时,通常都会做一个验证码,大家都知道用来防止暴力注册的,当然提到验证码大家都知道C#里面有一个Bitmap类专门用来处理图片的,好吧,这一篇我们从最简单的"图片灰度化"说起. 一:图片灰度化 我们都知道,位图是由一个一个像素点组成的,像素点可能是红色,橙色,粉色等等,这些颜色我们都知道是用RGB来表示的. 每个颜色分量都是一个

  • Python图像运算之图像点运算与灰度化处理详解

    目录 一.图像点运算概念 二.图像灰度化处理 三.基于像素操作的图像灰度化处理 1.最大值灰度处理方法 2.平均灰度处理方法 3.加权平均灰度处理方法 四.总结 一.图像点运算概念 图像点运算(Point Operation)指对于一幅输入图像,将产生一幅输出图像,输出图像的每个像素点的灰度值由输入像素点决定.点运算实际上是灰度到灰度的映射过程,通过映射变换来达到增强或者减弱图像的灰度.还可以对图像进行求灰度直方图.线性变换.非线性变换以及图像骨架的提取.它与相邻的像素之间没有运算关系,是一种简

  • Python批量将图片灰度化的实现代码

    技术关键 os 模块的使用 使用 os.getcwd 获取当前路径 使用 os.listdir()获取文件列表 使用 os.path.splitext() 分割文件名和扩展名 使用 PLI 的 convert('L') 方法将图片转为灰度 代码实现 from PIL import Image import os path = os.getcwd() # 获取当前路径 file_list = os.listdir() for file in file_list: filename = os.pat

  • python图片灰度化处理的几种方法

    今天在学习的时候,发现scipy.misc中的imread提取图片的方法被弃用了.太生气了! 只好使用了matplotlib.pyplot中的imread了,可是当我发现他不能直接通过True来提取灰度图片时,我崩溃了 上网查了一下,了解了灰度化处理的几种方法: 首先先解释一下,彩色图片一般是由RGB组成,其实就是3个二维数组叠加而成.我们也就能看到一些彩色图片了.当R=G=B时,彩色图片就会变成一种灰度颜色,就是我们俗称的"黑白照片".所以灰度颜色的图片其实就是一个二维数组. 灰度化

  • Android中屏幕密度和图片大小的关系详解

    Android中屏幕密度和图片大小的关系详解 前言 Android中支持许多资源,包括图片(Bitmap),对应于bitmap的文件夹是drawable,除了drawable,还有drawable-ldpi.drawable-mdpi.drawable-hdpi.drawable-xhdpi.drawable-xxhdpi等,同一张图片放到上面不同的文件夹中是有区别的,比如一张100 * 100像素大小的图片,分别放在上述各个文件夹中,然后将其设置为ImageView(假设宽高都是wrap_co

  • flutter中的资源和图片加载示例详解

    目录 封面图 指定相应的资源 资源绑定 Asset bundling 资源变体 加载资源 加载文本资源 加载图片 加载依赖包中的图片 最后 封面图 下个季度的目标是把前端监控相关的内容梳理出来,梳理出来之后可能会在公司内部做个分享- Flutter应用程序既括代码也包括一些其他的资产,我们通常这些资产为资源. 有时候我会思考assets这个单词,在程序中到底应该翻译为资产呢?还是翻译为资源?按照习惯,我们这里还是称为资源好了- 这些资源是一些与应用程序捆绑在一起和并且部署应用时会用到的的文件,在

  • python实现图片处理和特征提取详解

    这是一张灵异事件图...开个玩笑,这就是一张普通的图片. 毫无疑问,上面的那副图画看起来像一幅电脑背景图片.这些都归功于我的妹妹,她能够将一些看上去奇怪的东西变得十分吸引眼球.然而,我们生活在数字图片的年代,我们也很少去想这些图片是在怎么存储在存储器上的或者去想这些图片是如何通过各种变化生成的. 在这篇文章中,我将带着你了解一些基本的图片特征处理.data massaging 依然是一样的:特征提取,但是这里我们还需要对跟多的密集数据进行处理,但同时数据清理是在数据库.表.文本等中进行.这是如何

  • Python图像运算之图像阈值化处理详解

    目录 一.图像阈值化 二.固定阈值化处理 1.二进制阈值化 2.反二进制阈值化 3.截断阈值化 4.阈值化为0 5.反阈值化为0 三.自适应阈值化处理 四.总结 一.图像阈值化 图像阈值化(Binarization)旨在剔除掉图像中一些低于或高于一定值的像素,从而提取图像中的物体,将图像的背景和噪声区分开来. 灰度化处理后的图像中,每个像素都只有一个灰度值,其大小表示明暗程度.阈值化处理可以将图像中的像素划分为两类颜色,常见的阈值化算法如公式(1)所示: 当某个像素点的灰度Gray(i,j)小于

  • Python OpenCV实现图片预处理的方法详解

    目录 一.图片预处理 1.1 边界填充(padding) 1.2 融合图片(mixup) 1.3 图像阈值 二.滤波器 2.1 均值滤波器 2.2 方框滤波器 2.3 高斯滤波器 2.4 中值滤波 2.5 所有滤波器按照上述顺序输出 一.图片预处理 1.1 边界填充(padding) 方法 : cv2.copyMakeBorder BORDER_REPLICATE:复制法,也就是复制最边缘像素. BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abc

随机推荐