• 说说C#进行数字图像处理的方法


    C#处理数字图像主要有以下的3种方法类

    • Bitmap类
    • BitmapData类
    • Graphics类

    Bitmap类


    Bitmap只要用于处理由像素数据定义的图像的对象,主要方法和属性如下:
    GetPixel方法和SetPixel方法,获取和设置一个图像的指定像素的颜色。
    PixelFormat属性,返回图像的像素格式。
    Palette属性,获取或折纸图像所使用的颜色调色板。
    Height属性和Width属性,返回图像的高度和宽度。
    LockBits方法和UnlockBits方法,分别锁定和解锁系统内存中的位图像素。

    BitmapData类


    BitmapData对象指定了位图的属性:
    Height属性,被锁定位图的高度。
    Width属性,被锁定位图的宽度。
    PixelFormat属性,数据的实际像素格式。
    Scan0属性,被锁定数组的首字节地址。
    Stride属性,步幅,也称扫描宽度。

    彩色图象灰度化
    24位彩色图象每个像素用3个字节表示,每个字节对应着R、G、B分量的亮度(红、绿、蓝)。当3个分量不想同时表现为灰度图像。下面有三种转换公式:
    Gray(I,j)为转换后的灰度图像在(I,j)点出的灰度值。由于人眼对颜色的感应不同,有了下面的转换公式:
    观察发现绿色所占比重最大,所以转换时直接使用G值作为转换结果:
    图像处理的3种方法分别是:提取像素法、内存法和指针法,它们各自有各自的特点。

    提取像素法
    使用的是GDI+中的Bitmap.GetPixel和Bitmap.SetPixel方法。

    if (bitmap != null)
    {
    newbitmap = bitmap.Clone() as Bitmap;
    Color pixel;
    int ret;
    for (int x = 0; x < newbitmap.Width; x++)
    {
    for (int y = 0; y < newbitmap.Height; y++)
    {
    pixel = newbitmap.GetPixel(x, y);
    ret = (int)(pixel.R * 0.299 + pixel.G * 0.587 + pixel.B * 0.114);
    newbitmap.SetPixel(x, y, Color.FromArgb(ret, ret, ret));
    }
    }
    pictureBox1.Image = newbitmap.Clone() as Image;
    }

    内存法
    内存法是把图像数据直接复制到内存中,这样程序的运行速度就能大大提高了。
    if (bitmap != null)
    {
    newbitmap = bitmap.Clone() as Bitmap;
    Rectangle rect = new Rectangle(0, 0, newbitmap.Width, newbitmap.Height);
    System.Drawing.Imaging.BitmapData bmpdata = newbitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, newbitmap.PixelFormat);
    IntPtr ptr = bmpdata.Scan0;
    int bytes = newbitmap.Width * newbitmap.Height * 3;
    byte[] rgbvalues = new byte[bytes];
    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbvalues, 0, bytes);
    double colortemp = 0;
    for (int i = 0; i < rgbvalues.Length; i += 3)
    {
    colortemp = rgbvalues[i + 2] * 0.299 + rgbvalues[i + 1] * 0.587 + rgbvalues[i] * 0.114;
    rgbvalues[i] = rgbvalues[i + 1] = rgbvalues[i + 2] = (byte)colortemp;
    }
    System.Runtime.InteropServices.Marshal.Copy(rgbvalues, 0, ptr, bytes);
    newbitmap.UnlockBits(bmpdata);
    pictureBox1.Image = newbitmap.Clone() as Image;
    }

    指针法
    这个方法和内存法相似,开始都是通过LockBits方法来获取位图的首地址,这个方法更简洁,直接用指针进行位图操作。所以对内存的操作需要在unsafe下进行操作。
    if (bitmap != null)
    {
    newbitmap = bitmap.Clone() as Bitmap;
    Rectangle rect = new Rectangle(0, 0, newbitmap.Width, newbitmap.Height);
    System.Drawing.Imaging.BitmapData bmpdata = newbitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, newbitmap.PixelFormat);
    byte temp;
    unsafe
    {
    byte* ptr = (byte*)(bmpdata.Scan0);
    for (int x = 0; x < bmpdata.Width; x++)
    {
    for (int y = 0; y < bmpdata.Height; y++)
    {
    temp = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]);
    ptr[0] = ptr[1] = ptr[2] = temp;
    ptr += 3;
    }
    ptr += bmpdata.Stride - bmpdata.Width * 3;
    }
    }
    newbitmap.UnlockBits(bmpdata);
    pictureBox1.Image = newbitmap.Clone() as Image;
    }
    3种方法的比较
    时间消耗分别是:10583 160 147

    比较一下可以得出结论,提取像素法比较简单,但是效率比较低;内存法效率有了很大的提高,但是代码比较复杂;
    指针法效率比内存法更高一些,但是不安全。
    综上比较结果内存法比较好,效率即高又能发挥C#安全的优点。


    看了感觉怎么样?来说说吧。。。
    喜欢记得关注起来!赶紧的。


  • 相关阅读:
    redux核心知识
    react性能优化要点
    react-router4的使用备注
    selenium启动Chrome配置参数问题
    Navicat15最新版本破解和破解报错总结
    Silence主题美化-部署
    vscode打开文件,中文显示乱码(已解决)
    Windows下Charles从下载安装到证书设置和浏览器抓包
    python下的selenium和chrome driver的安装
    Python 直接赋值、浅拷贝和深度拷贝解析
  • 原文地址:https://www.cnblogs.com/eyesonchip/p/13725403.html
Copyright © 2020-2023  润新知