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方法。
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种方法的更多相关文章
- (转)C#进行图像处理的几种方法(Bitmap,BitmapData,IntPtr)
转自 http://blog.sina.com.cn/s/blog_628821950100wh9w.html C#进行图像处理的几种方法 本文讨论了C#图像处理中Bitmap类.BitmapData ...
- 使用C#进行图像处理的几种方法(转)
本文讨论了C#图像处理中Bitmap类.BitmapData类和unsafe代码的使用以及字节对齐问题. Bitmap类 命名空间:System.Drawing 封装 GDI+ 位图,此位图由图形图像 ...
- [转]使用C#进行图像处理的几种方法
最近做监控图像由彩色变灰处理的时候发现图像处理过程中,很慢很慢代码如下: int Height = this.picInfo.Image.Height; int ...
- 使用MATLAB对图像处理的几种方法(上)
实验一图像的滤波处理 一.实验目的 使用MATLAB处理图像,掌握均值滤波器和加权均值滤波器的使用,对比两种滤波器对图像处理结果及系统自带函数和自定义函数性能的比较,体会不同大小的掩模对图像细节的影响 ...
- 使用MATLAB对图像处理的几种方法(下)
试验报告 一.试验原理: 图像点处理是图像处理系列的基础,主要用于让我们熟悉Matlab图像处理的编程环境.灰度线性变换和灰度拉伸是对像素灰度值的变换操作,直方图是对像素灰度值的统计,直方图均衡是对 ...
- Java 返回一个整数的各个数字之和的一种方法
public static long sumDigits(long n){ long total=0; long number=n; while(number!=0){ total=total+num ...
- C#随机数字生成的一种方法
1.参考: public class RandomLongGenerater { public static long New(int bit) { ) { throw new Exception(& ...
- MATLAB数字图像处理(一)基础操作和傅立叶变换
数字图像处理是一门集计算机科学.光学.数学.物理学等多学科的综合科学.随着计算机科学的发展,数字图像处理技术取得了巨大的进展,呈现出强大的生命力,已经在多种领域取得了大量的应用,推动了社会的发展.其中 ...
- 《HALCON数字图像处理》第一、二章笔记
目录 第一章 绪论 1.1 图像和图像处理 1.1.1 图像 1.1.2 数字图像 1.1.3 图像处理及其发展过程 1.2 数字图像处理的步骤和方法 1.3 数字图像处理系统的硬件组成 1.4 数字 ...
随机推荐
- JavaScript中依赖注入详细解析
计算机编程的世界其实就是一个将简单的部分不断抽象,并将这些抽象组织起来的过程.JavaScript也不例外,在我们使用JavaScript编写应用时,我们是不是都会使用到别人编写的代码,例如一些著名的 ...
- 关于this的使用
一.关于this的使用 javaScript的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境 二.具体到实际应用中,this指向大致可以分为 ...
- linux 虚拟机下配置tomcat
1.在wind系统下载tomcat,tomcat8版本的需要jdk1.8以上的才支持. 下载位置:http://tomcat.apache.org/download-80.cgi -> core ...
- Flas-SQLAchemy数据库操作使用学习笔记
Flas-SQLAchemy数据库操作使用学习笔记 Flask-SQLALchemy 是一个给你的应用添加 SQLALchemy 支持的 Flask 扩展.SQLALchemy 是Python语言的S ...
- linux —— 问题解决(锦集)
这里收录了我在使用ubuntu 时遇到的问题以及解决方案. 1. Ubuntu上由于/boot容量不足引起的无法更新系统 解决: [ link1 ] [ link2 ] 2. 在未联网的情况下,sud ...
- 通过jdbc取得数据库表结构信息
做制作开发平台时,首要的一点是如何取得数据库表结构信息.一般通用的做法就是通过JDBC中的ResultSetMetaData类来进行操作,当你取得了数据库表结构信息后,比如说表的每个字段名称,字段类型 ...
- 枚举的基本使用方法 Enumerations
枚举的基本使用方法 Enumerations Enumeration enum SomeEnumeration{ case enumeration1 case enumeration2 case ...
- 【解决】hive动态添加partitions不能超过100的问题
Author: kwu [解决]hive动态添加partitions不能超过100的问题,全量动态生成partitions超过100会出现例如以下异常: The maximum number of d ...
- 【解决】WordPress FTP连接服务器时出错,请检查设置,WordPress需要访问您网页服务器的权限
刚装好wordpress,发现后台预装了两个插件,想删掉,结果要登录FTP,死活登不上去,提示"连接服务器时出错,请检查设置,WordPress需要访问您网页服务器的权限",网上也 ...
- tomcat结合nginx使用 基础教程
相信很多人都听过nginx,这个小巧的东西慢慢地在吞食apache和IIS的份额.那究竟它有什么作用呢?可能很多人未必了解. 说到反向代理,可能很多人都听说,但具体什么是反向代理,很多人估计就不清楚了 ...