оттенки серого в значении цвета - PullRequest
1 голос
/ 23 марта 2011

Я получаю от камеры значения оттенков серого для каждого пикселя в формате 23453 ... (16-битные значения) И я устанавливаю цвет пикселя для моего .bmp с помощью

image.SetPixel(cols, rows, color);

, но как мне получить мойсерое значение в правильное значение цвета?Таким образом, изображение может быть правильно отображаться в оттенках серого?

спасибо

1 Ответ

1 голос
/ 23 марта 2011
 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 #.

enter image description here

Перетащите 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 умножение матрицы скорость равна is (n ^ 2), но это линейное преобразование GDI + использует Быстрое преобразование Фурье , чтобы сделать это в Θ (n log (n)).Это означает для больших изображений, это намного быстрее, чем другие методы.

Допустим, у меня есть входные пиксели In со значениями {R, G, B, A} , и я хотел бы получить формулу для значений пикселей после умножения матрицы, и пустьНазовите это Out со значениями {A out , B out , C out , D out } .

enter image description here

Out:

  • 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

или в этом случае:

enter image description here

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.Так что это правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...