C#图像的灰度化处理:提取像素法

为了加快图像的处理速度,在图像处理算法中,往往需要把彩色图像转换为灰度图像

24位彩色图像每个像素用3个字节表示,每个字节对应着R、G、B分量的亮度。当RGB分量值不同时,表现为彩色图像,当RGB分量值相同时,表现为灰度图像。

求灰度值的方法:

  1. 平均值法
    将彩色图像中的三分量亮度求平均得到一个灰度图。
    f( i,j)=( R( i,j)+ G( i,j)+ B( i,j)) /3
  2. 加权平均法
    根据重要性及其它指标,将三个分量以不同的权值进行加权平均。由于人眼对绿色的敏感最高,对蓝色敏感最低,因此,按下式对RGB三分量进行加权平均能得到较合理的灰度图像。
    f( i,j)=0.30 R( i,j)+0.59 G( i,j)+0.11 B( i,j))

灰度前后对比效果图:

实例: 

复制代码
  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Drawing.Imaging;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 namespace gray
 10 {
 11     public partial class Form1 : Form
 12     {
 13         public Form1()
 14         {
 15             InitializeComponent();
 16             myTimer = new HiPerfTimer();
 17         }
 18         //打开图像
 19         private void open_Click(object sender, EventArgs e)
 20         {
 21             OpenFileDialog opnDlg = new OpenFileDialog();//创建OpenFileDialog对象
 22             //为图像选择一个筛选器
 23             opnDlg.Filter = "所有图像文件 | *.bmp; *.pcx; *.png; *.jpg; *.gif;"+ 
 24                 "*.tif; *.ico; *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf|" +
 25                 "位图( *.bmp; *.jpg; *.png;...) | *.bmp; *.pcx; *.png; *.jpg; *.gif; *.tif; *.ico|" +
 26                 "矢量图( *.wmf; *.eps; *.emf;...) | *.dxf; *.cgm; *.cdr; *.wmf; *.eps; *.emf";
 27             opnDlg.Title = "打开图像文件";
 28             opnDlg.ShowHelp = true;//启动帮助按钮
 29             if (opnDlg.ShowDialog() == DialogResult.OK)
 30             {
 31                 curFileName = opnDlg.FileName;
 32                 try
 33                 {
 34                     curBitmap = (Bitmap)Image.FromFile(curFileName);//使用Image.FromFile创建图像对象
 35                 }
 36                 catch (Exception exp)
 37                 {
 38                     MessageBox.Show(exp.Message);
 39                 }
 40             }
 41             //使控件的整个图面无效并导致重绘控件
 42             Invalidate();//对窗体进行重新绘制,这将强制执行Paint事件处理程序
 43         }
 44 
 45         private void save_Click(object sender, EventArgs e)
 46         {
 47             if(curBitmap == null)
 48             {
 49                 return;
 50             }
 51             SaveFileDialog saveDlg = new SaveFileDialog();
 52             saveDlg.Title = "保存为";
 53             saveDlg.OverwritePrompt = true;
 54             saveDlg.Filter =
 55                 "BMP文件 (*.bmp) | *.bmp|" +
 56                 "Gif文件 (*.gif) | *.gif|" +
 57                 "JPEG文件 (*.jpg) | *.jpg|" +
 58                 "PNG文件 (*.png) | *.png";
 59             saveDlg.ShowHelp = true;
 60             if(saveDlg.ShowDialog() == DialogResult.OK)
 61             {
 62                 string fileName = saveDlg.FileName;
 63                 string strFilExtn = fileName.Remove(0, fileName.Length - 3);
 64                 switch (strFilExtn)
 65                 {
 66                     case "bmp":
 67                         curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Bmp);
 68                         break;
 69                     case "jpg":
 70                         curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
 71                         break;
 72                     case "gif":
 73                         curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Gif);
 74                         break;
 75                     case "tif":
 76                         curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Tiff);
 77                         break;
 78                     case "png":
 79                         curBitmap.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
 80                         break;
 81                     default:
 82                         break;
 83                 }
 84             }
 85         }
 86 
 87         private void close_Click(object sender, EventArgs e)
 88         {
 89             this.Close();
 90         }
 91         /// <summary>
 92         /// 当一个应用程序需要进行绘制时,他必须通过Graphics对象来执行绘制操作
 93         /// 获取Graphics对象的方法有好几种,这里我们使用窗体Paint事件的PaintEventArgs属性来获取一个与窗体相关联的Graphics对象
 94         /// </summary>
 95         /// <param name="sender"></param>
 96         /// <param name="e"></param>
 97         private void Form1_Paint(object sender, PaintEventArgs e)
 98         {
 99             Graphics g = e.Graphics;//获取Graphics对象
100             if(curBitmap != null)
101             {
102                 g.DrawImage(curBitmap, 160, 20, curBitmap.Width, curBitmap.Height);//使用DrawImage方法绘制图像
103             }
104         }
105         /// <summary>
106         /// 提取灰度法
107         /// 为了将位图的颜色设置为灰度或其他颜色,需要使用GetPixel来读取当前像素的颜色--->计算灰度值--->使用SetPixel应用新的颜色
108         /// </summary>
109         private void pixel_Click(object sender, EventArgs e)
110         {
111             if(curBitmap != null)
112             {
113                 myTimer.ClearTimer();
114                 myTimer.Start();
115                 Color curColor;
116                 int ret;
117                 //二维图像数组循环  
118                 for (int i = 0; i < curBitmap.Width; i++)
119                 {
120                     for (int j = 0; j < curBitmap.Height ; j++)
121                     {
122                         //读取当前像素的RGB颜色值
123                         curColor = curBitmap.GetPixel(i,j);
124                         //利用公式计算灰度值(加权平均法)
125                         ret = (int)(curColor.R * 0.299 + curColor.G * 0.587 + curColor.B * 0.114);
126                         //设置该点像素的灰度值,R=G=B=ret
127                         curBitmap.SetPixel(i, j, Color.FromArgb(ret, ret, ret));
128                     }
129                 }
130                 myTimer.Stop();
131                 timeBox.Text = myTimer.Duration.ToString("####.##") + " 毫秒";
132                 //使控件的整个图面无效并导致重绘控件
133                 Invalidate();//对窗体进行重新绘制,这将强制执行Paint事件处理程序
134             }
135         }              
136     }
137 }
 

参考文献:C#数字图像处理算法典型实例(网上有PDF版)

转载请注明出处:http://www.cnblogs.com/hongfei/archive/2013/01/13/2858403.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值