zoukankan      html  css  js  c++  java
  • 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.30R(i,j)+0.59G(i,j)+0.11B(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

  • 相关阅读:
    CodeForces19D:Points(线段树+set(动态查找每个点右上方的点))
    CodeForces-816B:Karen and Coffee (简单线段树)
    CodeForces292D:Connected Components (不错的并查集)
    CodeForces546D:Soldier and Number Game(筛区间素数因子个数和)
    CoderForces343D:Water Tree(dfs序+线段树&&特殊处理)
    HihoCoder1706 : 末尾有最多0的乘积(还不错的DP)
    HihoCoder1705: 座位问题(STL)
    【CQ18阶梯赛第8场】题解
    阿里开源 Dragonwell JDK 重磅发布 GA 版本:生产环境可用
    5年时间,我从开发做到总裁的秘籍--如何提升技术型管理者的领导力
  • 原文地址:https://www.cnblogs.com/hongfei/p/2858403.html
Copyright © 2011-2022 走看看