彩色图像灰度化

彩色图像灰度化一般有四种方式:

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;
        }
posted @ 2012-04-17 14:49  trirocky  阅读(1046)  评论(0编辑  收藏  举报