C#数字图像处理的3种方法

本文主要通过彩色图象灰度化来介绍C#处理数字图像的3种方法,Bitmap类、BitmapData类和Graphics类是C#处理图像的的3个重要的类。

Bitmap只要用于处理由像素数据定义的图像的对象,主要方法和属性如下:

GetPixel方法和SetPixel方法,获取和设置一个图像的指定像素的颜色。

PixelFormat属性,返回图像的像素格式。

Palette属性,获取或折纸图像所使用的颜色调色板。

Height属性和Width属性,返回图像的高度和宽度。

LockBits方法和UnlockBits方法,分别锁定和解锁系统内存中的位图像素。

BitmapData对象指定了位图的属性:

Height属性,被锁定位图的高度。

Width属性,被锁定位图的宽度。

PixelFormat属性,数据的实际像素格式。

Scan0属性,被锁定数组的首字节地址。

Stride属性,步幅,也称扫描宽度。

彩色图象灰度化

24位彩色图象每个像素用3个字节表示,每个字节对应着R、G、B分量的亮度(红、绿、蓝)。当3个分量不想同时表现为灰度图像。下面有三种转换公式:

Gray(I,j)为转换后的灰度图像在(I,j)点出的灰度值。由于人眼对颜色的感应不同,有了下面的转换公式:

观察发现绿色所占比重最大,所以转换时直接使用G值作为转换结果:

图像处理的3种方法分别是:提取像素法、内存法和指针法,它们各自有各自的特点。

提取像素法

使用的是GDI+中的Bitmap.GetPixel和Bitmap.SetPixel方法。

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

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;

}

内存法

内存法是把图像数据直接复制到内存中,这样程序的运行速度就能大大提高了。

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

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下进行操作。

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

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种方法的比较

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

下载:DEMO

时间: 2024-08-26 16:28:31

C#数字图像处理的3种方法的相关文章

(转)C#进行图像处理的几种方法(Bitmap,BitmapData,IntPtr)

转自 http://blog.sina.com.cn/s/blog_628821950100wh9w.html C#进行图像处理的几种方法 本文讨论了C#图像处理中Bitmap类.BitmapData类和unsafe代码的使用以及字节对齐问题. Bitmap类 命名空间:System.Drawing 封装 GDI+ 位图,此位图由图形图像及其属性的像素数据组成.Bitmap 是用于处理由像素数据定义的图像的对象. 利用C#类进行图像处理,最方便的是使用Bitmap类,使用该类的GetPixel(

js字符串或则布尔值转换成数字类型的四种方法

1.parseInt() 2.parseFloat() 3.Number() 4.通过减法或者乘法把其他类型的值转换为数字类型 例子: // 转换成数字类型的4种方法 // 1.parseInt var a = '1.03'; var b = '1.01a'; var c = 'a1'; var d = true; var e = false; console.log(parseInt(a)); // 1 小数字符串,使用parseInt会把小数取整 console.log(parseInt(b

使用C#进行图像处理的几种方法(转)

本文讨论了C#图像处理中Bitmap类.BitmapData类和unsafe代码的使用以及字节对齐问题. Bitmap类 命名空间:System.Drawing 封装 GDI+ 位图,此位图由图形图像及其属性的像素数据组成.Bitmap 是用于处理由像素数据定义的图像的对象. 利用C#类进行图像处理,最方便的是使用Bitmap类,使用该类的GetPixel()与SetPixel()来访问图像的每个像素点.下面是MSDN中的示例代码: public void GetPixel_Example(Pa

第50件事 数字预测的2种方法

最近被KPI考核的事弄得焦头烂额,因为上级领导经常拍脑门决定考核的目标,也不管他人是否有能力实现.目标定得太高,难以实现:太低,又太容易实现,没什么挑战.到底什么样的目标数值是比较靠谱的?想学点数字预测的知识和技能,那如何做数字预测?数字预测指的是利用相关数据分析和挖掘模型预测出可能的数值,辅助决策,而不是拍脑门决策.产品运营过程中,经常会用到数据的精细化运营,而数字预测将会是精细化运营中非常重要的一项工作. 1.移动均值预测移动均值预测是最简单的一种数字预测方法,使用移动均值可预测商品销售数据

js中数字转换为字符串 几种方法

a. 要把一个数字转换为字符串,只要给它添加一个空的字符串即可: var n = 100; var n_as_string = n + ""; b. 要让数字更加显式地转换为字符串,可以使用String()函数:  var string_value = String(number); c. 使用toString()方法:  string_value = number.toString(); Number对象的(基本的数字转换为Number对象,以便可以调用这个方法)toString()

Java 返回一个整数的各个数字之和的一种方法

public static long sumDigits(long n){ long total=0; long number=n; while(number!=0){ total=total+number%10; number=(number-number%10)/10; } return total; } public static void testSumDigits(){ System.out.println("Enter a long integer: "); Scanner

26 计算用户输入的内容中索引为奇数并且对应的元素为数字的个数的两种方法

#计算用户输入的内容中索引为奇数并且对应的元素为数字的个数第二种方法content = input(">>>")count = 0for i in range(len(content)):#i就是下标,或者说就是索引 if i % 2 == 1 and content[i].isdigit(): count += 1print(count) #计算用户输入的内容中索引为奇数并且对应的元素为数字的个数的第一种方法 li = []res = ' '.join(input(

MATLAB数字图像处理(一)基础操作和傅立叶变换

数字图像处理是一门集计算机科学.光学.数学.物理学等多学科的综合科学.随着计算机科学的发展,数字图像处理技术取得了巨大的进展,呈现出强大的生命力,已经在多种领域取得了大量的应用,推动了社会的发展.其中,遥感领域中,对于影像数据的处理均基于数字图像处理的技术.而遥感影像数据作为地理信息科学的重要数据源,如何从中获取有用的信息,是地理信息数据处理中重要的内容. MATLAB作为数学领域应用最广泛的一种软件,集成了对于图片处理的函数和功能,成为了处理数字图像问题的佼佼者.其出众的计算能力和简便的绘图能

C#数字图像处理算法学习笔记(一)--C#图像处理的3中方法

C#数字图像处理算法学习笔记(一)--C#图像处理的3中方法 Bitmap类:此类封装了GDI+中的一个位图,次位图有图形图像及其属性的像素数据组成.因此此类是用于处理像素数据定义的图形的对象.该类的主要方法和属性如下:  GetPixel与SetPixel方法:获取或设置一个图像的指定像素的颜色. PixelFormat属性:返回图像的像素格式. Height和Width:返回图像的高度和宽度. LockBits与UnLockBits方法:分别锁定和解锁系统内存中的位图像素. LockBits