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

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

什么是图片灰度化?

在计算机图形学中,灰度化是一种将图片从彩色图转化为灰度图的处理过程。灰度图不同于彩色图,它只有黑白两色,其颜色是通过将红色、绿色和蓝色通道加权平均得到的。

实现灰度化的方法

像素级操作法

像素级操作法是一种对图片进行遍历,针对每个像素点单独处理的方法。具体实现是将每个像素点的 R、G、B 通道值按一定权重进行加权平均,从而得到该像素点的灰度值。

例如将红色、绿色、蓝色通道所占权值分别设置为 0.3、0.59、0.11,则某个像素点的灰度值计算公式如下:

灰度值 = R * 0.3 + G * 0.59 + B * 0.11

矩阵法

矩阵法是一种利用数字矩阵对图像进行卷积运算的灰度化方法。它采用 3 x 3 的卷积核对图片进行卷积操作,从而得到灰度图。

卷积核一般采用下面这种方式来设置:

| -1 | -1 | -1 |
| -1 | 8 | -1 |
| -1 | -1 | -1 |

采用上述卷积核时,处理的方式如下:

  1. 将待处理的图片按照矩阵方式放置;
  2. 对每个像素进行卷积操作,得到一个新的像素值,并将新的像素值赋值给该像素点。

经过矩阵卷积后,得到的结果是一个灰度图。

实现代码示例

像素级操作法

Bitmap bmp = new Bitmap("image.jpg");

for (int i = 0; i < bmp.Width; i++)
{
    for (int j = 0; j < bmp.Height; j++)
    {
        Color color = bmp.GetPixel(i, j);

        int grayValue = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);
        Color newColor = Color.FromArgb(color.A, grayValue, grayValue, grayValue);
        bmp.SetPixel(i, j, newColor);
    }
}

bmp.Save("grayImage.jpg");

上述代码使用像素级操作法实现了图片的灰度化。

矩阵法

Bitmap bmp = new Bitmap("image.jpg");

int[,] matrix = new int[3, 3]{
    {-1, -1, -1},
    {-1,  8, -1},
    {-1, -1, -1}
};

BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;

unsafe
{
    byte* p = (byte*)(void*)Scan0;

    int nOffset = stride - bmp.Width * 3;

    for (int y = 0; y < bmp.Height - 2; ++y)
    {
        for (int x = 0; x < bmp.Width - 2; ++x)
        {
            int grayValue =
                matrix[0, 0] * (p + y * stride + x * 3)[0] +
                matrix[0, 1] * (p + y * stride + x * 3 + 3)[0] +
                matrix[0, 2] * (p + y * stride + x * 3 + 6)[0] +
                matrix[1, 0] * (p + (y + 1) * stride + x * 3)[0] +
                matrix[1, 1] * (p + (y + 1) * stride + x * 3 + 3)[0] +
                matrix[1, 2] * (p + (y + 1) * stride + x * 3 + 6)[0] +
                matrix[2, 0] * (p + (y + 2) * stride + x * 3)[0] +
                matrix[2, 1] * (p + (y + 2) * stride + x * 3 + 3)[0] +
                matrix[2, 2] * (p + (y + 2) * stride + x * 3 + 6)[0];

            if (grayValue > 255)
            {
                grayValue = 255;
            }

            if (grayValue < 0)
            {
                grayValue = 0;
            }

            (p + (y + 1) * stride + x * 3 + 1)[0] = (byte)grayValue;
            (p + (y + 1) * stride + x * 3 + 2)[0] = (byte)grayValue;
            (p + (y + 1) * stride + x * 3)[0] = (byte)grayValue;
        }
    }
}
bmp.UnlockBits(bmData);
bmp.Save("grayImage.jpg");

上述代码使用矩阵法实现了图片的灰度化。

总结

实现图片灰度化主要有两种方法:像素级操作法和矩阵法。像素级操作法的代码相对简单,但是速度较慢;矩阵法的代码相对复杂,但是速度较快。针对不同的应用场景选择不同的方法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c#中实现图片灰度化技术详解 - Python技术站

(0)
上一篇 2023年6月7日
下一篇 2023年6月7日

相关文章

  • 基于NET Core 的Nuget包制作、发布和运用流程解析(完整过程)

    基于.NET Core的Nuget包制作、发布和运用流程解析(完整过程) NuGet是.NET平台上的包管理器,它可以帮助我们管理和分享.NET代码。在.NET Core中,NuGet包是一种重要的组件,它可以帮助我们轻松地共享和重用代码。在本文中,我们将介绍如何制作、发布和使用基于.NET Core的NuGet包。 制作NuGet包 制作NuGet包的步骤…

    C# 2023年5月16日
    00
  • asp.net 验证码生成和刷新及验证

    asp.net验证码生成 在asp.net中生成验证码需要使用Captcha控件,该控件可以生成图片验证码并且可以自定义验证码字符集合,大小,颜色等等。 首先需要在aspx页面中引入该控件: <%@ Register Assembly="System.Web.UI.WebControls" Namespace="Syste…

    C# 2023年6月1日
    00
  • C#多线程Singleton(单件)模式模板

    C#多线程Singleton(单件)模式模板是一种在多线程环境下保证对象只被创建一次并且可以被多线程共享的设计模式。下面我将提供一个完整的攻略来帮助大家了解如何在C#中实现多线程Singleton模式。 步骤一: 创建Singleton模板类 创建一个Singleton模板类,确保只有一个实例可以被创建。示例代码如下: public sealed class…

    C# 2023年5月31日
    00
  • .NET2.0版本中基于事件的异步编程模式(EAP)

    . 简介: 基于事件的异步编程模式(EAP)是.NET Framework 2.0 中引入的一种编程模式,是一种异步编程的方式,与.NET中的APM(异步编程模型)和TPL(任务并行库)不同,入口点不是Beginxxx和Endxxx方法或Task的异步方法,而是定义了异步方法并触发事件来通知异步操作完成。异步执行单元采用回调函数注册的方式,通过在异步操作完成…

    C# 2023年6月6日
    00
  • log4net创建系统日志的详细步骤

    log4net是一个Apache的开源项目,是一个.NET平台下的日志记录组件。它可以帮我们方便的记录系统日志,支持多种不同的记录方式,比如控制台输出,写入文件,发送到远程服务器等。下面详细讲解在.NET项目中使用log4net创建系统日志的详细步骤,包括配置、使用以及示例。 步骤一:安装log4net 在开始使用log4net创建系统日志之前,我们需要先安…

    C# 2023年5月31日
    00
  • C#数组中List, Dictionary的相互转换问题

    C#数组中List, Dictionary的相互转换是常见的问题,下面是一些详细的解答。 将List转换为数组 如果你有一个List对象想要转换成数组,可以使用List类的ToArray()方法。示例代码如下: List<int> list = new List<int> { 1, 2, 3 }; int[] array = list…

    C# 2023年6月1日
    00
  • 简单掌握Windows中C#启动外部程序进程的方法

    下面我将详细介绍如何在Windows中使用C#启动外部程序进程的方法。 1. 引用命名空间 在使用C#启动外部程序进程前,需要先引用System.Diagnostics命名空间,该命名空间包含了一个名为Process的类,用于处理进程相关操作。 using System.Diagnostics; 2. 创建Process对象 创建Process对象是启动外部…

    C# 2023年6月7日
    00
  • C#递归应用之实现JS文件的自动引用

    下面我将详细讲解“C#递归应用之实现JS文件的自动引用”的完整攻略,包括过程和示例。 背景介绍 在网页中,经常需要引入多个JS文件,但是手动一个一个引入比较麻烦,而且还容易出错。因此,我们可以通过C#递归应用实现JS文件的自动引用。 实现步骤 具体实现步骤如下: 获取指定文件夹下所有.js文件的路径 将这些路径添加到HTML代码的头文件中 如果JS文件中还有…

    C# 2023年6月7日
    00
合作推广
合作推广
分享本页
返回顶部