本文主要通过彩色图象灰度化来介绍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方法。

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

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

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

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

    转自 http://blog.sina.com.cn/s/blog_628821950100wh9w.html C#进行图像处理的几种方法 本文讨论了C#图像处理中Bitmap类.BitmapData ...

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

    本文讨论了C#图像处理中Bitmap类.BitmapData类和unsafe代码的使用以及字节对齐问题. Bitmap类 命名空间:System.Drawing 封装 GDI+ 位图,此位图由图形图像 ...

  3. [转]使用C#进行图像处理的几种方法

    最近做监控图像由彩色变灰处理的时候发现图像处理过程中,很慢很慢代码如下: int Height = this.picInfo.Image.Height;                    int ...

  4. 使用MATLAB对图像处理的几种方法(上)

    实验一图像的滤波处理 一.实验目的 使用MATLAB处理图像,掌握均值滤波器和加权均值滤波器的使用,对比两种滤波器对图像处理结果及系统自带函数和自定义函数性能的比较,体会不同大小的掩模对图像细节的影响 ...

  5. 使用MATLAB对图像处理的几种方法(下)

     试验报告 一.试验原理: 图像点处理是图像处理系列的基础,主要用于让我们熟悉Matlab图像处理的编程环境.灰度线性变换和灰度拉伸是对像素灰度值的变换操作,直方图是对像素灰度值的统计,直方图均衡是对 ...

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

    public static long sumDigits(long n){ long total=0; long number=n; while(number!=0){ total=total+num ...

  7. C#随机数字生成的一种方法

    1.参考: public class RandomLongGenerater { public static long New(int bit) { ) { throw new Exception(& ...

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

    数字图像处理是一门集计算机科学.光学.数学.物理学等多学科的综合科学.随着计算机科学的发展,数字图像处理技术取得了巨大的进展,呈现出强大的生命力,已经在多种领域取得了大量的应用,推动了社会的发展.其中 ...

  9. 《HALCON数字图像处理》第一、二章笔记

    目录 第一章 绪论 1.1 图像和图像处理 1.1.1 图像 1.1.2 数字图像 1.1.3 图像处理及其发展过程 1.2 数字图像处理的步骤和方法 1.3 数字图像处理系统的硬件组成 1.4 数字 ...

随机推荐

  1. 【HDOJ】1423 Greatest Common Increasing Subsequence

    LCIS /* 1423 */ #include <cstdio> #include <cstring> #include <cstdlib> #define MA ...

  2. 【性能测试】【Jmeter】学习(2)——录制一段脚本

    打开JMeter工具,录制一段脚本(我做的是录制登陆网站后点击设备的开关设定,然后再退出) 1).创建一个线程组(右键点击“测试计划”--->“添加”---->“线程组”) 2).添加录制 ...

  3. LeetCode——Majority Element

    在一个数组中找到主要的元素,也就是出现次数大于数组长度一半的元素.容易想到的方式就是计数,出现次数最多的就是majority element,其次就是排序,中间的就是majority element. ...

  4. mongDB 的使用

    首先是启动 mongdb的service ,不启用的话,使用mong shell 连接的现象是: 启动服务端,指定默认的存储的位置即可: mongod  -- dbpath  F:/store  #数 ...

  5. C primer plus 读书笔记第八章

    本章的标题是字符输入/输出和输入确认.主要内容是讨论用于I/O的标准函数. 1.getchar()和putchar() 这两个函数之前用过,我们通过这两个函数来讨论下缓冲区. #include &qu ...

  6. 获取Android自己写好了的apk以及反编译

    今天,我们先说一下,获取Android自带的apk以及反编译它们来学习Android工程师是怎样写的,今天我们就以拿到Android自带的短信管理器的apk为例子 你可能有疑问,为什么要那么麻烦,从系 ...

  7. IntelliJ IDEA 中module的dependencies是其它module时的注意事项

    Dependencies on other modules If a module (module A) depends on another module (module B), IntelliJ ...

  8. Java基础知识强化69:基本类型包装类之Character案例(统计字符串中大写小写以及数字的次数)

    我们直接看案例如下: package cn.itcast_03; import java.util.Scanner; /* * 统计一个字符串中大写字母字符,小写字母字符,数字字符出现的次数.(不考虑 ...

  9. Linux LVM 扩展磁盘分区

    系统:centos 6.3--新建分区 fdisk -l /dev/sdc       # 查看分区 fdisk /dev/sdc          # 创建分区 :n                 ...

  10. ASP.NET-FineUI开发实践-9(三)

    1. TextChanged事件前台触发回发后台,接上文,先给TextBox1加上事件,看看是怎么生成出来的, 注意AutoPostBack="true",找源代码,f4多出了个 ...