热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

来源:http:zxlovenet.cnblogs.com本文主要通过彩色图象灰度化来介绍C#处理数字图像的3种方法,Bitmap类、BitmapData类和Graphics类是C

来源: http://zxlovenet.cnblogs.com 

本文主要通过彩色图象灰度化来介绍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
    {
        for (int y = 0; 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
    {
        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
        {
            for (int y = 0; 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#安全的优点。

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


推荐阅读
  • BL550721、特点液晶驱动输出:Common输出4线,Segment输出36线内置显示寄存器364144bit2线串行接口(SCL,SDA)内置震荡电路内置液晶驱动电源电路13 ... [详细]
  • 深入解析Android Activity生命周期
    本文详细探讨了Android中Activity的生命周期,通过实例代码和详细的步骤说明,帮助开发者更好地理解和掌握Activity各个阶段的行为。 ... [详细]
  • 本文详细介绍了一种实现PopupWindow全屏显示且能有效隐藏虚拟按键的技术方案,适用于Android开发。此方法经过实际测试,表现良好,兼容性优秀。 ... [详细]
  • BeautifulSoup4 是一个功能强大的HTML和XML解析库,它能够帮助开发者轻松地从网页中提取信息。本文将介绍BeautifulSoup4的基本功能、安装方法、与其他解析工具的对比以及简单的使用示例。 ... [详细]
  • HDU1085 捕获本·拉登!
    问题描述众所周知,本·拉登是一位臭名昭著的恐怖分子,他已失踪多年。但最近有报道称,他藏匿在中国杭州!虽然他躲在杭州的一个洞穴中不敢外出,但近年来他因无聊而沉迷于数学问题,并声称如果有人能解出他的题目,他就自首。 ... [详细]
  • 本视频详细介绍了如何利用J2EE、JBPM 3.x/4.3、Flex流程设计器、jQuery以及授权认证机制构建高效的企业普及版贝斯OA及工作流管理系统。 ... [详细]
  • 本文介绍了如何在Windows操作系统中安装FFTW库,并详细说明了使用Visual Studio 2010进行4096点快速傅里叶变换(FFT)的步骤。包括下载预编译文件、生成库文件以及配置环境等关键环节。 ... [详细]
  • IEC60825激光产品安全标准详解
    随着激光技术在全球范围内的广泛应用,尤其是激光投影显示技术的兴起,了解和遵守相关的安全标准变得尤为重要。本文将详细介绍IEC60825激光产品安全标准及其重要性。 ... [详细]
  • Mysqlcheck作为MySQL提供的一个实用工具,主要用于数据库表的维护工作,包括检查、分析、修复及优化等操作。本文将详细介绍如何使用Mysqlcheck工具,并提供一些实践建议。 ... [详细]
  • 探讨并提供解决方案以应对 'view is not in the window hierarchy' 的错误提示。 ... [详细]
  • 本文介绍了如何处理MySQL数据库中表 'xdb.auditlog' 被标记为已损坏的问题,并提供了解决方案。 ... [详细]
  • 本文介绍了多种Eclipse插件,包括XML Schema Infoset Model (XSD)、Graphical Editing Framework (GEF)、Eclipse Modeling Framework (EMF)等,涵盖了从Web开发到图形界面编辑的多个方面。 ... [详细]
  • 在使用KVM虚拟化技术通过NAT模式启动虚拟机时,可能会遇到qemu-ifup-nat脚本执行失败的错误。本文将详细介绍如何诊断和解决这一问题。 ... [详细]
  • 本文介绍了Linux内核中TCP的三种接收队列:Prequeue、sk_receive_queue和Backlog。这些队列在数据包处理过程中扮演着重要角色,帮助提高系统性能和效率。 ... [详细]
  • Redis: 高效的键值存储系统
    Redis是一款遵循BSD许可的开源高性能键值存储系统,它不仅支持多种数据类型的存储,还提供了数据持久化和复制等功能,显著区别于其他键值缓存解决方案。 ... [详细]
author-avatar
晴天逍遥
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有