彩色图转为灰度图的场景非常多,比如人工智能的训练与识别时,需要将彩色图片转为灰度图。
以下文字来自于:
彩色图像转灰度图像原理python_蜗牛的笨笨的博客-CSDN博客_python 彩色图转灰度图现在我们所接触到的图像绝大多数都是数字图像,图像数字化后,每个像素点就可以看作是一个小方格,每个小方格里面存储的就是图像的像素信息。如果把一副数字图像抽象出来,就是一个二维矩阵(灰度图)或者三维矩阵(彩色图)。任何颜色都有红、绿、蓝三原色组成。用红、绿、蓝三元组的二维矩阵来表示(这样构成了三个通道),抽象出来一起构成了一个三维数组。https://blog.csdn.net/qq_44820108/article/details/121702791
数字图像
数字化的图像,实际上是一个网格(数组)。每个网格点存储图像的像素信息。如果把一副数字图像抽象出来,就是一个二维矩阵(灰度图)或者三维矩阵(彩色图)。
彩色图像
一般意义上,颜色都由红Red、绿Green、蓝Blue三原色组成。用红、绿、蓝三元组的二维矩阵来表示(这样构成了三个通道),抽象出来一起构成了一个三维数组。三元组的每个数值也是在0-255之间,0表示相应的基色在该像素中没有,而255表示相应的基色在该像素中取得最大值。通过调节每个通道数灰度值的亮度,从而对三个通道中的三种基色进行不同搭配,进而构成了五颜六色的彩色世界!
灰度图像
每个像素的亮度用一个数值来表示,取值范围0-255,0表示黑、255表示白,其他值表示处于黑白之间的灰度,抽象出来构成了一个二维数组。灰度图像就没有色彩了,他的颜色是介于黑色到白色。255表示白色,0表示黑色,灰度等级处于之间就表示成不同等级的灰色。
图像转换
彩色图像转换成灰度图像最基本的就是考虑怎么去分配三个通道里面的灰度等级,如果单纯直接将R通道里面的灰度值全部拿出来,会构成一个灰度图像。
通过以下几种方法来转换彩色图像的三个通道的灰度值:
浮点算法:Gray=0.299R+0.587G+0.114B
整数方法:Gray=(R30+G59+B*11)/100
移位方法:Gray=(R28+G151+B*77)>>8
平均值法:Gray=(R+G+B)/3
上面公式中的R、G、B表示这三个通道里面的灰度值。对不同通道里的灰度值进行加权,加权后得到的灰度值就是我们转换后的灰度图的灰度值,所以这样得到的灰度图像更符合我们人眼的直观映像。转换后存到对应的二维数组里面,这个数组就是转换后的灰度图像抽象意义上的二维数组,显示出来就是一副灰度图像。
以下代码是经过实践检验的,可用:
using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
namespace Legalsoft.Truffer
{
public static class BitmapHelper
{
/// <summary>
/// 彩色图片转为灰度图的快速算法
/// </summary>
/// <param name="bmp"></param>
private static void QuickToGrayImage(Bitmap bmp)
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
IntPtr ptr = bmpData.Scan0;
int bytes = bmpData.Stride * bmpData.Height;
byte[] data = new byte[bytes];
Marshal.Copy(ptr, data, 0, bytes);
int zz = 0;
for (int y = 0; y < bmpData.Height; y++)
{
for (int x = 0, zn = zz; x < bmpData.Width; x++)
{
int gray = (int)(data[zn + 2] * 0.299 + data[zn + 1] * 0.587 + data[zn] * 0.114);
byte ct = (byte)((gray > 254) ? 255 : (gray < 1) ? 0 : (byte)(gray));
data[zn + 2] = data[zn + 1] = data[zn] = ct;
zn += 3;
}
zz += bmpData.Stride;
}
Marshal.Copy(data, 0, ptr, bytes);
bmp.UnlockBits(bmpData);
}
/// <summary>
/// 彩色图片转为灰度图的原始算法
/// </summary>
/// <param name="bmp"></param>
private static void ToGrayImage(Bitmap bmp)
{
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmp.Width; x++)
{
Color cc = bmp.GetPixel(x, y);
int cx = Math.Min(255, (int)(cc.R * 0.299 + cc.G * 0.587 + cc.B * 0.114));
bmp.SetPixel(x, y, Color.FromArgb(cx, cx, cx));
}
}
}
}
}
B-21?
更期待 H-20