彩色图像灰度化
彩色图像灰度化一般有四种方式:
1、分量法
将彩色图像中的三分量的亮度作为三个灰度图像的灰度值
f1(i,j)=R(i,j),f2(i,j)=G(i,j),f3(i,j)=B(i,j)
2、最大值法
f(i,j)=max(R(i,j),G(i,j),B(i,j))
3、平均值法
f(i,j)=(R(i,j),G(i,j),B(i,j))/3
4、加权平均法
根据人眼敏感度对RGB三分量进行加权平均
f(i,j)=0.299*R(i,j)+0.587*G(i,j)+0.114*B(i,j)
据此发现,绿色所占比例最大,又可近似为
f(i,j)=G(i,j)
本篇采用第四种方法
public static Bitmap RGB2Gray(Bitmap srcBitmap) { int width = srcBitmap.Width; int height = srcBitmap.Height; Rectangle rect = new Rectangle(0, 0, width, height); BitmapData srcBmData = srcBitmap.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); Bitmap dstBitmap = CreateGrayscaleImage(width, height); BitmapData dstBmData = dstBitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); System.IntPtr srcScan = srcBmData.Scan0; System.IntPtr dstScan = dstBmData.Scan0; unsafe { byte* srcP = (byte*)(void*)srcScan; byte* dstP = (byte*)(void*)dstScan; int srcOffset = srcBmData.Stride - width * 3; int dstOffset = dstBmData.Stride - width; byte red, green, blue; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++, srcP += 3, dstP++) { //注意其实际顺序为BGR blue = srcP[0]; green = srcP[1]; red = srcP[2]; *dstP = (byte)(.299 * red + .587 * green + .114 * blue); } srcP += srcOffset; dstP += dstOffset; } } srcBitmap.UnlockBits(srcBmData); dstBitmap.UnlockBits(dstBmData); return dstBitmap; } private static Bitmap CreateGrayscaleImage(int width, int height) { Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed); SetGrayscalePalette(bmp); return bmp; } private static void SetGrayscalePalette(Bitmap srcImg) { if (srcImg.PixelFormat != PixelFormat.Format8bppIndexed) throw new ArgumentException(); ColorPalette cp = srcImg.Palette; for (int i = 0; i < 256; i++) cp.Entries[i] = Color.FromArgb(i, i, i); srcImg.Palette = cp; }