`
wooce
  • 浏览: 184736 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

C#中如何高性能地把图像转换成grayscale的

    博客分类:
  • C#
阅读更多

C#里把图片灰度化: 先是用以下代码, 能转换, 但经测试性能比较低, 在窗口中预览灰度化的采集视频, 相当卡顿, 这是因为在两重循环里大量调用GetPixel和SetPixel

        private Bitmap rgb2gray(Bitmap bm)
        {
            //Row-wise iteration through the Bitmap 
            for (int y = 0; y < bm.Height; y++)
            {
                for (int x = 0; x < bm.Width; x++)
                {
                    Color pixelColor = bm.GetPixel(x, y);
 
                    int pixelLuminance = (int)(pixelColor.R * 0.2126 + pixelColor.G * 0.7152 + pixelColor.B * 0.0722);
 
                    bm.SetPixel(x, y, Color.FromArgb(pixelLuminance, pixelLuminance, pixelLuminance));
                }//for
            }//for
 
            return bm;
        }//rgb2gray(Bitmap)

 

经搜索, 在http://stackoverflow.com/questions/1580130/high-speed-performance-of-image-filtering-in-c-sharp 里找到以下代码: 

public static void GrayScaleImage(Bitmap image)
{
    if (image == null)
        throw new ArgumentNullException("image");

    // lock the bitmap.
    var data = image.LockBits(
                  new Rectangle(0, 0, image.Width, image.Height), 
                  ImageLockMode.ReadWrite, image.PixelFormat);
    try
    {
        unsafe
        {
            // get a pointer to the data.
            byte* ptr = (byte*)data.Scan0;

            // loop over all the data.
            for (int i = 0; i < data.Height; i++)
            {
                for (int j = 0; j < data.Width; j++)
                {
                    // calculate the gray value.
                    byte y = (byte)(
                        (0.299 * ptr[2]) + 
                        (0.587 * ptr[1]) + 
                        (0.114 * ptr[0]));

                    // set the gray value.
                    ptr[0] = ptr[1] = ptr[2] = y;

                    // increment the pointer.
                    ptr += 3;
                }

                // move on to the next line.
                ptr += data.Stride - data.Width * 3;
            }
        }
    }
    finally
    {
        // unlock the bits when done or when 
        // an exception has been thrown.
        image.UnlockBits(data);
    }
}

 

 改用以上代码, 经测试, 性能可以, 但是处理后的图片有些问题, 左边的大部分灰度化的区域有栅格, 右边有一小段区域没有灰度化.  这当然难不倒老杨,  老杨感觉是ptr指向的索引不正确的问题,  参考了下其他代码(https://github.com/baobaohuang/Graphic_gray/blob/cd1d9b543762c23a8fc232e21f8de15dd810e8b2/gray/Program.cs  , 这个也可以工作, 性能高于最初的代码,但低于上面的代码),  修正代码如下: 

        public static void GrayScaleImage(Bitmap image)
        {
            if (image == null)
                throw new ArgumentNullException("image");

            // lock the bitmap.
            var data = image.LockBits(
                          new Rectangle(0, 0, image.Width, image.Height),
                          ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            try
            {
                unsafe
                {
                    // get a pointer to the data.
                    byte* ptr = (byte*)data.Scan0;

                    // loop over all the data.
                    for (int i = 0; i < data.Height; i++)
                    {
                        ptr = (byte*)data.Scan0 + i*data.Stride;
                        for (int j = 0; j < data.Width; j++)
                        {
                            // calculate the gray value.
                            byte y = (byte)(
                                (0.299 * ptr[2]) +
                                (0.587 * ptr[1]) +
                                (0.114 * ptr[0]));

                            // set the gray value.
                            ptr[0] = ptr[1] = ptr[2] = y;

                            // increment the pointer.
                            ptr += 3;
                        }

                    }
                }
            }
            finally
            {
                // unlock the bits when done or when 
                // an exception has been thrown.
                image.UnlockBits(data);
            }
        }

 

最后测试, 以上代码效果perfect !  不过后来发现, 其实两段代码的处理ptr的方式都一样可以, 主要是

var data = image.LockBits(
                          new Rectangle(0, 0, image.Width, image.Height),
                          ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

 这里必须用PixelFormat.Format24bppRgb

0
0
分享到:
评论

相关推荐

    C# 将彩色图片转换为灰度图片

    在图像处理领域,将彩色图片转换为灰度图片是一种常见的操作。这主要涉及到色彩空间的转换,其中最常见的是从RGB(红绿蓝)色彩空间转换到灰度色彩空间。在C#编程语言中,我们可以利用.NET框架提供的System.Drawing...

    c#平台下基于Bitmap的高性能图像处理基础算法源代码

    在C#平台上,基于Bitmap的图像处理是一种常见的技术,用于创建、编辑和操作图像。Bitmap类是.NET Framework中用于处理像素级别的图像的核心类,提供了丰富的功能来实现各种图像处理算法。以下将详细介绍标题和描述中...

    C#图像分隔

    在C#编程环境中,图像处理是一项重要的任务,尤其在创建图形用户界面(GUI)或进行数字图像分析时。本文将深入探讨如何利用`System.Drawing.Graphics`类中的`DrawImage`方法来实现图像编辑,以及与图像分隔相关的...

    C#常用滤镜

    总之,将C++滤镜改写为C#,意味着可以利用C#的现代特性,如垃圾回收、强类型检查和丰富的类库,同时保持C++滤镜的高性能和成熟算法。这个过程涉及对C++和C#两者的深入理解,以及对图像处理算法的熟悉。通过以上介绍...

    C#调用matlab画图,解决图像嵌入Winform窗体和首次画图慢的问题

    这里的关键是利用`MWFunctionManager`来调用MATLAB函数,并通过`MWImageUtilities`将返回的图像数据转换为C#中的`Bitmap`对象,然后显示在pictureBox控件中。 关于首次画图慢的问题,可能的原因有: 1. MATLAB组件...

    C# UnmanagedImage

    《C#中的UnmanagedImage:图像处理与OpenCV的结合》 在计算机视觉领域,图像处理是一项基础且关键的技术。在.NET环境中,C#作为常用的语言之一,虽然提供了丰富的类库如System.Drawing来处理图像,但对一些高级的...

    如何以黑白方式显示图像

    在实际应用中,你可能需要根据具体的需求进行优化,比如处理大量图像时考虑性能问题,或者使用更高级的算法如自适应阈值法来提高转换效果。但上述代码提供了一个基本的起点,让你能够理解如何在C#中以源码方式实现...

    C#程式碼引用windows api將圖片轉灰階

    在本文中,我们将深入探讨如何使用C#编程语言引用Windows API来将图片转换为灰阶。这种方法相较于.NET Framework内建的方式,可能提供更高的性能优化,特别是在处理大量图像时。我们将首先介绍Windows API的基本概念...

    DFT.rar_CSharp opencv_DFT_opencv_opencv csharp

    结合OpenCV,我们可以创建高性能的图像处理应用。在C#中调用OpenCV主要是通过OpenCV的.NET接口,这使得C#开发者能够方便地利用OpenCV的强大功能。 首先,我们需要了解离散傅立叶变换(DFT)的基本概念。DFT是一个...

    gabor.zip_图形图像处理_C#_

    C#是微软开发的一种面向对象的编程语言,具有丰富的库支持和高效的执行性能,非常适合用于开发图像处理应用。在C#中实现Gabor滤波器,我们可以利用.NET Framework或.NET Core提供的System.Drawing或OpenCVSharp等库...

    FreeImage库

    5. **多线程安全**:FreeImage的设计考虑了多线程环境,可以安全地在多个线程中同时使用,这对于需要并发处理图像的高性能应用来说是个重要特性。 6. **插件系统**:FreeImage有一个可扩展的插件系统,允许添加对新...

    OpenCvForUnity

    这段代码展示了如何读取一张图片并将其转换为灰度图像,然后将结果显示在游戏对象上。 三、OpenCV在Unity中的高级应用 1. 特征检测与匹配 OpenCV提供了多种特征检测算法,如SIFT、SURF和ORB等。这些算法可以用于...

Global site tag (gtag.js) - Google Analytics