Распознавание и обработка изображений


Роботы и обработка изображений

Представление изображений в памяти

Исходным цветом монитора является чёрный, а все остальные цвета на нем получаются при помощи комбинации трех цветов различной интенсивности - красного, зеленого и синего. image 1 Минимальный элемент изображения на мониторе, это 3 рядом стоящие точки, красного, зеленого и синего цветов. Если приглядеться, или посмотреть на монитор через линзу, их можно увидеть. Такой триплет называется пикселом (pixel), как сокращение от picture element. Интенсивность красного, зеленого и синего компонет (RGB) задается числом от 0 до 255. 0 соответствует наименьшей интенсивности, 255 наибольшей. Таким образом, любую картинку можно описать при помощи таких наборов из трех чисел.

image 1

Каждое число, описывающее компонент пиксела, умещается в 8 бит, и весь пиксел описывается при помощи 24 битов. Иногда можно встретить другое представление пикселя, где максимальная интенсивность компоненты 5 или 6 бит и пиксел описывается 16-битным числом. Такое представление часто можно встретить на переносных устройствах, вроде телефонов. Также встречается 32-битное представление, где первые 8 бит описывают величину прозрачности пиксела. Такие представления я рассматривать не буду, и делее везде будет предполагаться (если отдельно не оговорено) 24-битное представление пикселя.

Каждое прямоугольное электронное изображение характеризуется шириной и высотой. Ширина такого изображения это количество столбцов из пикселей, а высота - количество строк. В памяти компьютера удобно хранить такое изображение последовательно, слева направо и сверху вниз. Пусть H - высота изображения, а W - его ширина. Тогда размер памяти IM, который понадобиться для изображения равен H * W * 3 байт. Если мы хотим считать пиксель, с координатами картинки (x,y) из памяти, то нам нужно считать значение по адресу памяти A = (y * W + x) * 3. Тогда, по адресу A будет храниться красный компонент, по адресу А+1, зеленый и по адресу А+2, синий.

Напишем простейший класс на С++, который будет хранителем изображения и позволит обращаться к каждому пикселу:

 
class CImageCore
{
public:
  // конструктор
  CImageCore(int w, int h)
  {
      // размер памяти для изображения
      int size = w * h * 3;
 
      // выделяем память нужного размера
      m_image = new unsigned char[size];
 
      // сохраняем ширину и высоту изображения внутри класс
      m_width = w;
      m_height = h;
  }
  // в деструкторе освобождаем память
  ~CImageCore() { delete []m_image;  }
 
  // получить пиксель с координатами (x,y) из памяти
  unsigned long pixel(int x, int y)
  {
      // вычисляем адрес пикселя
      int a = (y * m_width + x) * 3;
 
      // получаем компоненты пикселя
      unsigned long R = image[A];
      unsigned long G = image[A+1];
      unsigned long B = image[A+2];
 
      // так мы представляем 8-битные компоненты пикселя в виде одного 32-битного числа.
      return (R << 16) | (G << 8) | B;
  }
 
  // установить для пикселя с координатами (x,y) значение цвета r,g,b
  void setPixel(int x, int y, int r, int g, int b)
  {
      // вычисляем адрес пикселя
      int a = (y * m_width + x) * 3;
 
      // сохраняем компоненты пикселя
      image[A] = r;
      image[A+1] = g;
      image[A+2] = b;
  }
 
  // получить ширину картинки
  int width() { return m_width; }
 
  // получить высоту картинки
  int height() { return m_height; }
 
protected:
  unsigned char *m_image; // массив картинки
  int m_width;   // ширина
  int m_height;  // высота            
};
 

Теперь у нас есть готовый объект для работы с изображениями в памяти.

0
4397
ivtst1
5 апреля 2014
Написать


Комментарии: