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#使用semaphore来管理异步下载请求的方法

    下面我将详细讲解“C#使用semaphore来管理异步下载请求的方法”的完整攻略。 什么是 Semaphore Semaphore(信号量)是一种用于控制访问资源的同步方式。它维护了一个计数器(初始值为一个正整数),用来标识可以访问某一资源的线程数量。当一个线程需要访问该资源时,它需要先对这个计数器进行减一操作,当计数器变为0时,该资源将不再被其他线程访问,…

    C# 2023年6月7日
    00
  • WinForm相对路径的陷阱

    WinForm相对路径的陷阱是指在Windows窗体应用程序中使用相对路径时可能会遇到的问题。在WinForm应用程序中,使用相对路径可以方便地引用外部文件,例如资源文件、配置文件、图片等,但是如果不注意一些细节,就会出现问题。下面是WinForm相对路径的完整攻略。 1. 了解相对路径和绝对路径 在开始之前,我们需要了解相对路径和绝对路径的概念。相对路径是…

    C# 2023年6月1日
    00
  • 详解StackExchange.Redis通用封装类分享

    详解StackExchange.Redis通用封装类分享 前言 本文主要介绍了StackExchange.Redis通用封装类的设计与使用,帮助开发人员更方便地使用Redis。 StackExchange.Redis介绍 StackExchange.Redis是一个开源的Redis驱动程序,是使用C#编写的,支持.NET Framework和.NET Cor…

    C# 2023年5月31日
    00
  • ASP.NET数组删除重复值实现代码

    下面为您详细讲解“ASP.NET数组删除重复值实现代码”的攻略过程: 1. 准备工作 首先,在进行数组删除重复值之前,需定义一个原始数组,此处用int类型数组为例: int[] array = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3}; 而在进行删除后,需定义一个新的数组来存储结果: int[] newArray = new int[ar…

    C# 2023年5月31日
    00
  • C#中函数的创建和闭包的理解

    C#中函数的创建和闭包的理解 函数创建 声明函数 在C#中使用function关键字来声明一个函数,语法格式为: visibility return_type function_name(parameter_list) { // function body } visibility:可见性修饰符,指定函数的访问范围,可以是public、private、pro…

    C# 2023年5月14日
    00
  • C# SaveFileDialog与OpenFileDialog用法案例详解

    C#SaveFileDialog与OpenFileDialog用法案例详解 SaveFileDialog SaveFileDialog用于显示一个保存文件的对话框。 基本用法 使用SaveFileDialog需要首先在程序中引用命名空间: using System.Windows.Forms; 然后创建一个SaveFileDialog对象,设置其属性,最后使…

    C# 2023年5月15日
    00
  • .net2.0+ Winform项目实现弹出容器层

    下面是“.net2.0+Winform项目实现弹出容器层”的攻略: 准备工作 首先,我们需要创建一个WinForms应用程序,然后添加一个Windows 窗体(Form)并设置一个按钮(Button)用于弹出容器控件。同时,我们需要通过NuGet包管理器安装一个叫做“MetroModernUI”的UI框架,这个框架提供了一些漂亮的样式和控件,可以让我们的UI…

    C# 2023年5月15日
    00
  • C#实现利用泛型将DataSet转为Model的方法

    下面是详细的讲解。 1. 确定需求 在实现将DataSet转为Model的方法前,需要先明确需求。本次需求是将DataSet中的数据转换为Model类型并返回。 2. 准备数据 假设我们有一个Student的类型,定义如下: public class Student { public int Id { get; set; } public string Na…

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