Member 13341679 Ответов: 3

Извлечение значения каналов RGB и отображать его


Здравствуйте, я хочу получить только значения RGB из изображения, присутствующего в поле изображения, и показать его на своей форме. Код, который я пробовал, дает целые значения пикселей( а также занимает слишком много времени для вычисления пикселей), но мне нужно показать только значения RGB. Пожалуйста помочь. Заранее спасибо.
Я работаю над обработкой изображений и использованием C#.Net, VS 2012. Я не использую EMGU CV.

Что я уже пробовал:

public void PixelValues()
        {
            newBitmap = (Bitmap)pictureBox1.Image;
            Bitmap pix = (Bitmap)newBitmap.Clone();
            for (int i = 0; i < pix.Width; i++)
            {
                for (int j = 0; j < pix.Height; j++)
                {
                    Color pixel = newBitmap.GetPixel(i, j);
                    int a = pixel.A;//Alpha
                    int r = pixel.R;
                    int g = pixel.G;
                    int b = pixel.B;

                    listBox1.Items.Add("Red: " + r.ToString() + " - " + "Green: " + g.ToString() + " - " + "Blue: " + b.ToString());
                }
            }
        }

3 Ответов

Рейтинг:
10

Member 13341679

Я нашел решение, и вот код. Это дает точный результат, который я хотел.

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (opened)
                {
                    newBitmap = (Bitmap)pictureBox1.Image;

                    label1.Text = "X= " + e.X + " ; Y= " + e.Y;//Gives mouse pointer coordinate on the image
                    Color color = newBitmap.GetPixel(e.Location.X, e.Location.Y);
                    label2.Text = string.Format("RGB Values:  {0}, {1}, {2}", color.R, color.G, color.B);//Returns pixel value at mouse position   
                }
        }


Рейтинг:
1

lukeer

Похоже, у вас есть две проблемы: 1) функция, 2) скорость.

1) отредактируйте свой вопрос: ваш код уже делает то, что вы хотите, только слишком медленно?
Если нет, то что ваш код делал не так, как вы хотели?

2 а) оберните свой код доступа к текстовому полю в

listBox1.SuspendLayout();
listBox1.Items.AddAllTheInterestingStuff();
listBox1.ResumeLayout();
Это экономит много времени, которое в противном случае тратится на перерисовку списка для каждой отдельной записи.

2 б) взгляните на Быстрая бессмысленная обработка изображений в .NET Он показывает способ ускорения доступа к данным изображений.


Рейтинг:
1

phil.o

В дополнение к решению 1 я хотел бы обратить ваше внимание на несколько вопросов:

1. Вам не нужно pix переменная, или, по крайней мере, не в том фрагменте кода, который вы показали. Удаление копии может сэкономить несколько циклов (но это тоже не будет радикальным улучшением).

2. Вам не нужно a переменная, так как вас не интересует Альфа-значение. Удаление его сэкономит изрядное количество циклов, так как его назначение выполняется внутри ваших вложенных циклов for. r, g и b переменные также не являются обязательными, если только они не предназначены для отладки; но если вы не хотите использовать их в другом месте, кроме как в построении строк, вы также можете избавиться от них.

3. конкатенации строк, особенно в длинных циклах, также довольно трудоемки, поскольку они включают в себя множество внутренних операций копирования строк. Здесь я хотел бы использовать StringBuilder чтобы попытаться получить некоторую производительность.
Таким образом:

using System.Text;

public void PixelValues()
{
   listBox1.SuspendLayout(); // Thanks to lukeer
   newBitmap = (Bitmap)pictureBox1.Image;
   Color pixel;
   StringBuilder sb = new StringBuilder(33); // 33 = max length of the string when all values are three digits long (quick count - could be wrong)
   for (int i = 0; i < pix.Width; i++)
   {
      for (int j = 0; j < pix.Height; j++)
      {
         pixel = newBitmap.GetPixel(i, j);
         sb.AppendFormat("Red: {0} - Green: {1} - Blue: {2}", pixel.R, pixel.G, pixel.B);
         listBox1.Items.Add(sb.ToString());
         sb.Clear();
      }
   }
   listBox1.ResumeLayout(); // Thanks to lukeer
}

Вы также можете использовать List<string> вместо того чтобы добавлять элементы в ListBox один за другим, и добавьте всю их кучу в конце с помощью AddRange метод проведения ListBox класс, но я не уверен, что это даст значительное улучшение. Но это можно проверить, просто чтобы быть уверенным.

Надеюсь, это поможет. Любезно.


Member 13341679

@phil.o никаких изменений в выводе, как и раньше.

phil.o

Просто из любопытства, какова ширина и высота изображения?

Member 13341679

Это динамично. Можно делать любые снимки. Это пользовательский интерфейс.

phil.o

Я все понял. Но что за изображение вы используете во время вашего теста?

Member 13341679

Обработка изображений, применение различных фильтров для повышения четкости изображения.

phil.o

Извините, это не мой вопрос. Каков размер фактического изображения, которое вы используете во время вашего теста, в частности?