1

我从相机中获取格式为 23453...(16 位值)的每个像素的灰度值,然后我为我的 .bmp 设置了像素颜色

image.SetPixel(cols, rows, color);

但是我怎样才能让我的灰度值变成正确的颜色值呢?那么图片可以正确的以灰度值显示吗?

谢谢

4

1 回答 1

1
 public static Bitmap getGrayscale(Bitmap hc){
        Bitmap result = new Bitmap(hc.Width, hc.Height);
        ColorMatrix colorMatrix = new ColorMatrix(new float[][]{   
            new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0.5f,0.5f,0.5f,0,0},
            new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0,0,0,1,0,0},
            new float[]{0,0,0,0,1,0}, new float[]{0,0,0,0,0,1}});

        using (Graphics g = Graphics.FromImage(result)) {
            ImageAttributes attributes = new ImageAttributes();
            attributes.SetColorMatrix(colorMatrix);
            g.DrawImage(hc, new Rectangle(0, 0, hc.Width, hc.Height),
               0, 0, hc.Width, hc.Height, GraphicsUnit.Pixel, attributes);
        }
        return result;
    }

这实际上是一个相当复杂的问题。在我的示例中,基本上我创建了一个过滤器并将其应用于现有位图,并进行了一些漂亮的矩阵计算。我之前解决了它,试图解决这个问题。

编辑

VB 的人喜欢完整的例子,也许 C# 也是如此。

在此处输入图像描述

将 2 个按钮和一个图片框放到一个表单上,然后使用代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;

namespace gray
{
    public partial class Example : Form
    {
        public Example()
        {
            InitializeComponent();
        }

        public static Bitmap getGrayscale(Bitmap hc)
        {
            Bitmap result = new Bitmap(hc.Width, hc.Height);
            ColorMatrix colorMatrix = new ColorMatrix(new float[][]{   
            new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0.5f,0.5f,0.5f,0,0},
            new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0,0,0,1,0,0},
            new float[]{0,0,0,0,1,0}, new float[]{0,0,0,0,0,1}});

            using (Graphics g = Graphics.FromImage(result))
            {
                ImageAttributes attributes = new ImageAttributes();
                attributes.SetColorMatrix(colorMatrix);
                g.DrawImage(hc, new Rectangle(0, 0, hc.Width, hc.Height),
                   0, 0, hc.Width, hc.Height, GraphicsUnit.Pixel, attributes);
            }
            return result;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog fDialog = new OpenFileDialog();
            fDialog.Title = "Open Image File";
            fDialog.Filter = "PNG Files|*.png|Bitmap Files|*.bmp";
            fDialog.InitialDirectory = @"C:\";

            if (fDialog.ShowDialog() == DialogResult.OK)
                this.pictureBox1.ImageLocation = fDialog.FileName.ToString();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (this.pictureBox1.Image == null)
            {
                MessageBox.Show("Sorry no image to alter.");
                return;
            }
            this.pictureBox1.Image = getGrayscale((Bitmap)this.pictureBox1.Image);
        }
    }
}

是的,这很有效,颜色平衡正确。

但是,如果您想要一个具有有效亮度的替代方案,那么:

    ColorMatrix colorMatrix = new ColorMatrix(new float[][]{   
                              new float[]{ 0.3f, 0.3f, 0.3f,0,0},
                              new float[]{0.59f,0.59f,0.59f,0,0},
                              new float[]{0.11f,0.11f,0.11f,0,0},
                              new float[]{    0,    0,    0,1,0,0},
                              new float[]{    0,    0,    0,0,1,0},
                              new float[]{    0,    0,    0,0,0,1}});

编辑 2:@Hans Passant。

位图由具有颜色值RGBA { R ed, G reen, B lue, A lpha 透明度} 的像素组成。为了从彩色图像中获取灰度图像,我将每个像素颜色值与我定义colorMatrix的 .

正常的2 矩阵乘法速度是 Θ(n^2),但是这个 GDI+ 线性转换使用快速傅里叶变换在 Θ(n log(n)) 中进行。这意味着对于更大的图像,它比其他方法快得多。

假设我有输入像素In,其值为{R, G, B, A}并且我想在矩阵乘法后得到像素值的公式,并Out用值{A out , B out , C out , D调用它}

在此处输入图像描述

出去:

  • A out = r(4) A + r(3) B + r(2) G + r(1) R
  • B out = g(4) A + g(3) B + g(2) G + g(1) R
  • C out = b(4) A + b(3) B + b(2) G + b(1) R
  • D out = a(4) A + a(3) B + a(2) G + a(1) R

或者在这种情况下:

在此处输入图像描述

Out = {
  0.11 B + 0.59 G + 0.3 R,
  0.11 B + 0.59 G + 0.3 R,
  0.11 B + 0.59 G + 0.3 R,
  A,
  0,
  0
}

其中灰度图像的有效亮度公式为0.11 blue + 0.59 green + 0.3 red。所以是正确的。

于 2011-03-23T19:15:10.990 回答