引用 celeron533 : 我比较好奇的是公式里的这些系数是怎么确定下来的
据传是人眼对各种颜色的敏感度不同。。。
C#中可以用ColorMatrix进行颜色变换。ColorMatrix由一个float[][]交错数组组成,5行5列。
横行表示5个颜色源:源R、源G、源B、源Alpha、源1
纵列表示5个颜色目标:目标R、目标G、目标B、目标Alpha、目标1(忽略)
灰度化公式:light = 0.299 * r + 0.587 * g + 0.114 * b
源代码如下:
<code class="language-cs">using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Imaging; using System.Text; using System.Windows.Forms; namespace grayscale { public partial class Form1 : Form { public Form1() { InitializeComponent(); } Bitmap colorBmp; Bitmap grayBmp; Bitmap GetGrayScale(Bitmap src) { // 灰度化公式: // light = 0.299 * r + 0.587 * g + 0.114 * b float[][] cmatdata = { new float[] {0.299f, 0.299f, 0.299f, 0, 0}, new float[] {0.587f, 0.587f, 0.587f, 0, 0}, new float[] {0.114f, 0.114f, 0.114f, 0, 0}, new float[] {0, 0, 0, 1, 0}, new float[] {0, 0, 0, 0, 1}, }; ColorMatrix cmat = new ColorMatrix(cmatdata); ImageAttributes imageattr = new ImageAttributes(); imageattr.SetColorMatrix(cmat); Bitmap graybmp = new Bitmap(src.Width, src.Height); Graphics.FromImage(graybmp).DrawImage( src, new Rectangle(0, 0, src.Width, src.Height), 0, 0, src.Width, src.Height, GraphicsUnit.Pixel, imageattr ); return graybmp; } private void button1_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "打开图片"; if (ofd.ShowDialog() == DialogResult.OK) { try { colorBmp = new Bitmap(ofd.FileName); grayBmp = GetGrayScale(colorBmp); Invalidate(); } catch (Exception err) { MessageBox.Show(err.ToString() + "\r\n" + err.StackTrace); } } } private void Form_Paint(object sender, PaintEventArgs e) { if (grayBmp != null) { e.Graphics.DrawImage(grayBmp, 0, 0, grayBmp.Width, grayBmp.Height); } } } } </code>
[修改于 8年6个月前 - 2016/06/25 12:14:04]
灰度化除了使用ColorMatrix以外,也可以自己逐个处理像素颜色,就是比较麻烦一点。除了这个公式以外,还有两个整数运算公式,分别适用于16位机和32位机:
上述整数运算适用于浮点运算能力差的处理器,实际上在现代Intel计算机上性能提升不明显。
还有一种据传是Adobe中的灰度化算法:
Adobe RGB (1998) [gamma=2.20]
light = (r ^ 2.2 * 0.2973 + g ^ 2.2 * 0.6274 + b ^ 2.2 * 0.0753) ^ (1 / 2.2)
速度慢,但是效果较好。
还有就是最简单的平均值算法,这个最原始,效果也较差。
最暴力的算法是直接拿绿色值作灰度,因为绿色最亮。
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |
200字以内,仅用于支线交流,主线讨论请采用回复功能。