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日

相关文章

  • C# 修改文件的创建、修改和访问时间的示例

    下面是在C#中修改文件的创建、修改和访问时间的示例: 修改文件创建、修改和访问时间 using System; using System.IO; class Program { static void Main() { // 指定要修改时间的文件路径 string filePath = "test.txt"; // 获取当前时间 Date…

    C# 2023年6月1日
    00
  • c#同步两个子目录文件示例分享 两个文件夹同步

    来讲解一下”C#同步两个子目录文件”以及”两个文件夹同步”的攻略。 I. 问题背景 我们的应用程序通常需要处理本地文件,并且在不同的设备之间进行同步和备份。 如果我们有一个目录,其中包含许多文件和子目录,我们可能需要将该目录以及它的所有内容复制到另一个位置以进行备份。 在这种情况下,我们需要一种可靠的方法来同步这两个目录,在一个目录中的任何更改都应反映在另一…

    C# 2023年6月1日
    00
  • 在C#中使用SQLite数据库

    轻量级桌面程序数据库不太适合用SQLServer、MySQL之类的重量级数据库,嵌入式数据库更好。在对比Access、SQLite、Firebird数据库后发现SQLite较另外两个有较多优点。 环境:.NET Framework 3.5、windows11 64位、Visual Studio 2010. C#使用SQLite需要从SQLite官网下载DLL…

    C# 2023年4月27日
    00
  • C# 实现与现有.NET事件桥接简单实例

    接下来我将为你详细讲解 “C# 实现与现有.NET事件桥接简单实例”的完整攻略。主要包括以下两个步骤: 步骤一:桥接现有.NET事件 C# 中实现与现有.NET事件桥接的方式,是通过使用 delegate 委托类型和 event 事件类型来实现的。 1.1 创建一个委托类型 public delegate void MyEventHandler(object…

    C# 2023年5月31日
    00
  • WCF实现进程间管道通信Demo分享

    下面是关于“WCF实现进程间管道通信Demo分享”的完整攻略,包含两个示例。 1. 什么是进程间管道通信 进程间管道通信是一种在不同进程之间进行通信的方法。在Windows操作系统中,可以使用命名管道(Named Pipe)来实现进程间管道通信。命名管道是一种命名的、双向的、异步的、字节流管道,可以在本地或远程计算机之间进行通信。 2. WCF实现进程间管道…

    C# 2023年5月15日
    00
  • C# StringBuilder.Clear()方法: 清空 StringBuilder 对象的内容

    StringBuilder.Clear()是一个C#中StringBuilder类中的方法,它的作用是清空该StringBuilder实例中的字符串缓存区,以便新的字符串能够追加到缓存区中。 其使用方法非常简单,在调用该方法时,所有的缓存字符串都会被清空,代码实现如下: StringBuilder sb = new StringBuilder(); sb.A…

    C# 2023年4月19日
    00
  • C# Linq的Single()方法 – 返回序列中的唯一元素

    C# Linq中Single()函数的完整攻略 Single()函数是C# Linq中的一个用于查询的函数,它返回一个序列中单个特定元素,如果序列包含多个元素,则会引发异常。这篇攻略会详细讲解Single()函数的用法,并提供一些示例来帮助读者理解。 语法 下面是Single()函数的语法: public static TSource Single<T…

    C# 2023年4月19日
    00
  • C#版Windows服务安装卸载小工具

    C#版Windows服务安装卸载小工具是一种方便的工具,可以用于安装、卸载和管理Windows服务。以下是使用C#实现Windows服务安装卸载小工具的完整攻略。 环境准备 在使用C#实现Windows服务安装卸载小工具前,需要确保以下环境已经准备好: Visual Studio已经安装并配置好了环境变量。 项目中已经添加了引入的包的依赖。 实现Window…

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