Стереоизображение — это просто

:

Привет, %username%.

В данной статье я хочу рассказать, как можно самостоятельно создать стереоизображение при помощи графического редактора и небольшой программы.
изображение-маска
стереоизображение

Введение


Для начала рассмотрим, как устроено стереоизображение и как на него смотреть. В первую очередь оно состоит из повторяющихся фрагментов.
рис  1.
рис 1.

Очень важно, чтобы ширина повторяющегося фрагмента была меньше, чем расстояние между глаз. Для комфортного просмотра стереоизображения ширина должна колебаться в пределах от 1/3 до 2/3 данной величины. Чем ширина больше, тем более глубокое (объемное) изображение можно получить. Чем меньше ширина, тем меньше устают глаза от просмотра стереоизображения.

Чтобы увидеть объемное изображение, необходимо сфокусировать взгляд за плоскостью рисунка таким образом, чтобы изображения для левого и правого глаз совпали. Для изображения, целиком состоящего из повторяющихся фрагментов, вы будете наблюдать точно такое же мнимое изображение (ровная плоскость). Единственное отличие – вам будет казаться, что рисунок стал располагаться дальше.
рис 2.
рис 2.

Как получается объемное изображение?


Чтобы изображение стало объемным, некоторые его части должны восприниматься, как более близкие, другие – как более удаленные. Данного эффекта можно достичь путем сдвига элементов изображения.

На рисунке 3 показано, как изменилось мнимое изображение, после сдвига двух элементов (красного и фиолетового) реального изображения на одну позицию влево.
рис 3.
рис 3.

На мнимом изображении образовалось два артефакта одинакового размера, равного размеру сдвинутых элементов. Артефакт, находящийся слева от места сдвига, воспринимается, как расположенный более близко к наблюдателю (перед плоскостью мнимого изображения). Артефакт справа, наоборот, воспринимается как расположенный за плоскостью мнимого изображения. О положении элементов мнимого изображения, которые одновременно видны только одному глазу (отмечены пунктирной линией), мозг «додумывает» самостоятельно.

Замечу, что сдвиг не должен превышать половины ширины повторяющейся части. Когда размер сдвига близок к этой границе, глазу трудно определить, выпукла или вдавлена наблюдаемая область.

Если мы хотим изображать объекты, расположенные только перед плоскостью мнимого изображения, нам необходимо уметь бороться с нежелательными артефактами. Для этого достаточно осуществить сдвиг элементов в каждом периоде, расположенном справа от первого места сдвига (рисунок 4).
рис 4.
рис 4.

Осталось показать, как на мнимом изображении формируются объекты с разной степенью удаленности. Для наглядного примера на сей раз осуществим сдвиг трех элементов влево, но не на одну позицию, а на две. Сравнивая рисунки 4 и 5, видим, что на последнем рисунке за счет сдвига на большее количество позиций, мы получили объект, расположенный ближе, чем при сдвиге на одну позицию.
рис 5.
рис 5.

Собственно реализация


Создавалось стереоизображение следующей функцией, написанной на C#:
private Bitmap GenerateStereoPicture(Bitmap bitmapMask)
{
  // Переводим маску в массив сдвигов
  int w = bitmapMask.Width;
  int h = bitmapMask.Height;
  int[][] mask = new int[w][];
  for (int x = 0; x < w; x++)
  {
    mask[x] = new int[h];
    for (int y = 0; y < h; y++)
      mask[x][y] = bitmapMask.GetPixel(x, y).R / 32;
  }

  // Cоздаем фон
  int s = 100;
  Bitmap stereoImg = GetNewStereoPicture(w + s, h, s);

  // Сдвигаем каждый пиксел
  for (int y = 0; y < h; y++)
    for (int x = 0; x < w; x++)
      if (mask[x][y] > 0)
      {
        Color pixel = stereoImg.GetPixel(x + mask[x][y], y);
        for (int i = x + s; i < w + s; i += s)
          stereoImg.SetPixel(i, y, pixel);
      }

  return stereoImg;
}

На входе функция принимает изображение-маску, созданное в графическом редакторе. Сперва была создана текстовая надпись, к которой затем была применена градиентная заливка (самый первый рисунок в статье).

Точки черного цвета трактуются функцией как точки с нулевым сдвигом, т.е. они формируют плоскость мнимого изображения. Чем ярче цвет точки, тем больше ее сдвиг, тем ближе она будет казаться наблюдателю. Так как изображение выполнено в серых цветах, то для определения яркости точки я использовал яркость красной составляющей RGB, поделенную на 32. Таким образом, максимально возможный сдвиг равен 255/32 = 7.

После формирования массива сдвигов, функция создает изображение шириной w+s пикселей, высотой h пикселей и с шириной повторяющейся части s = 100 пикселей. В качестве повторяющейся части я генерирую случайное изображение, состоящее из случайного количества случайных фигур (эллипс, прямоугольник, дуга, кривая) случайного размера и цвета. Вы же можете подойти к этому этапу творчески и заранее подготовить какой-нибудь красивый фон.

На заключительном, самом важном этапе осуществляется сдвиг каждого пикселя изображения в соответствии с массивом сдвигов.

P.S. Буду очень рад, если данная статья поможет кому-то хотя бы научиться смотреть стереоизображения, так как сам я далеко не сразу смог это освоить.