Как сделать стерео картинку в фотошопе
Создаём стереофото в домашних условиях!
Название «линзовый растр» знают немногие. Но видели его, я думаю, все. Вспомним переливающиеся под рифлёными пластиковыми поверхностями изображения – календарики, открытки, сувениры. Полосы на этом пластике образованы лежащими плотно друг к другу полуцилиндрами.
Изображение под линзовым растром состоит из полосок разных ракурсов изображения. Благодаря растру левый и правый глаз видят на одном и том же участке поверхности разные изображения.
Принцип действия линзового растра. Левый и правый глаз видят на одном и том же участке поверхности разные изображения
Принцип действия линзового растра. Левый и правый глаз видят на одном и том же участке поверхности разные изображения
Процесс создания стереофотографии в общих чертах достаточно прост.
Мы фотографируем интересующий нас объект с нескольких ракурсов, затем совмещаем полученные изображения с помощью соответствующего программного обеспечения и преобразуем в чересполосное изображение. После этого накладываем линзовый растр и получаем стереоизображение.
А теперь, убедившись в том, что всё просто, давайте посмотрим, как оно на самом деле. Потому что каждый из обозначенных этапов процесса имеет свои особенности и тонкости, и лучше сначала семь раз отмерить, чем семь раз отснять и впоследствии убедиться, что отснятые снимки ни на что не годны.
Если у нас один фотоаппарат для съёмки с разных ракурсов, то объект фотосъёмки должен быть неподвижным. Если объект подвижен, то нам потребуется единовременная съёмка с разных ракурсов. А это уже делается с помощью линеек камер, синхронизированных между собой. Впрочем, и неподвижных объектов для фотосъёмки найдётся немало. Более того, портретную стереосъёмку совершенно спокойно можно делать одной камерой, быстро перемещаемой по специальным рельсам.
Но для знакомства с технологией мы выберем что-нибудь попроще.
Сам процесс съёмки стереоракурсов может выполняться разными способами. Если это съёмка пейзажей и отдалённых объектов, камеру можно двигать прямолинейно, слева направо или справа налево, перемещаясь приставными шагами. В этом случае наше смещение в масштабах кадра невелико. Если же объект находится близко, перемещать камеру надо по окружности, центр которой находится внутри объекта. Иначе на втором-третьем кадре снимаемый объект просто исчезнет из поля зрения.
Величина смещения камеры в обоих случаях тоже не может быть произвольной: от неё зависят резкость итогового изображения, глубина резкости и размер картинки, который мы сможем напечатать.
В общем, перед началом съёмки желательно написать её сценарий и рассчитать все параметры съёмки с помощью программки MultiStereobase, которая входит в комплект поставки программы PhotoProjector Easy. Это программное обеспечение было любезно предоставлено мне его разработчиком – Евгенией Вазенмиллер.
Создать стерео 3D изображение в Photoshop
В этом уроке мы рассмотрим, как сделать из обычной фотографии стереоскопическую, как сейчас принято говорить, 3D-фото, кроме того, достаточно понятно объясняется принцип создания анаглифных фото.
Мы возьмём обычную фотографию и преобразуем её в 3D анаглифное изображение с помощью программы Adobe Photoshop.
Для просмотра такой фотографии в 3D необходимы анаглифные очки
Данный метод очень хорошо работает с черно-белыми изображениями, но, тем не менее, я считаю, что он работает довольно хорошо и с цветными фотографиями.
Открываем фото в Photoshop. Я воспользуюсь этой фотографией:
Дублируйте (Crtl+J) фоновое изображение два раза раза (по одному слою для каждого глаза). Переименуйте один дубликат в «левый-красный», а другой в «правый-голубой», чтобы избежать путаницы в дальнейшем. После этого выключите видимость на фонового слоя:
Мы будем манипулировать двумя новыми слоями так, чтобы картинки, видимые правым и левым глазом, несколько отличались друг от друга.
Разделяем цветовые каналы и изменяем перспективу изображения
3D анаглиф работает, используя нашу естественную способность воспринимать глубину с помощью бинокулярного зрения. Восприятие глубины исходит из того, что каждый из наших глаз видит несколько отличную от другого картинку. Наш мозг обрабатывает картинки, полученные каждым глазом, и на основе небольшой разницы в углах обзора между двумя изображениями получает ощущение глубины. Это основная предпосылка для работы техники, изложенной в данном уроке.
Мы начинаем с отделения цветовых каналов на каждом слое.
Большинство анаглифных 3D-очков поставляются с красными линзами для левого глаза и синей (бирюзовой) линзы для правого. Поскольку красная линза позволяет видеть только в красном канале, мы отключим зеленый и синий каналы для этого слоя. Отключение каналов можно сделать в диалоговом окне Параметров наложения (Blending Options).
В панели слоёв дважды кликните по слою «левый-красный», откроется диалоговое окно «Параметров наложения» (Blending Options), где снимите галки с каналов G и B:
Т.к. наш правый глаз будет в состоянии видеть только зеленый и синий (голубой) каналы через голубую линзу, мы отключим красный канал для слоя «правый-голубой»:
Теперь, когда мы разделили каналы для каждого глаза, назначив по слою для правого и левого глаза, моделируем глубину изображения, изменив перспективу каждого слоя.
Начнём с слоя «левый-красный». Отключите видимость слоя «правый-голубой». Для изменения перспективы воспользуемся инструментом
«Свободная трансформация» (Free Transform). Кликаем по слою «левый-красный» для его активации, затем нажимаем клавиши Ctrl+T. Вокруг слоя появляется габаритная рамка. Кликаем правой клавишей мыши в любом месте внутри рамки, в открывшемся контекстном меню нажимаем на пункт «Перспектива» (Perspective):
Перетащите верхний левый угол изображения вверх, как показано на картинке. Чем выше Вы его перетащите, тем более выраженным будет эффект объёма на фото:
Нажмите Enter для применения действия инструмента.
Отключите видимость слоя «левый-красный», включите видимость слоя «правый-голубой» и сделайте таким де образом трансформируйте его, только с правой стороны:
Включите видимость обеих слоёв, и у Вас получится примерно такое изображение:
Теперь, мы посмотрим на фото в 3D-очках, мы заставим наш мозг подумать, что он воспринимает два разных изображения. Но картинка не готова, т.к. центр изображения не совмещён. Исправим это с помощью инструмента «Перемещение» (Move Tool).
Сведение изображений и обрезка картинки
Возьмите инструмент «Перемещение», зажмите клавишу Shift и переместите слои вправо и влево соответственно, в качестве общего центра я использовал лицо модели. Для перемещения можно использовать не мышь, а клавиши «стрелка вправо» и «стрелка влево»:
Осталось только обрезать левый и правый край картинки с помощью инструмента «Обрезка» (Crop Tool) и сохранить документ.
Вот как выглядит готовое фото:
Хотя этот метод отличается от создания реального 3D анаглифного фото, где используются две фотокамеры, снимающие с разных углов, мы получили почти подобный эффект, используя только одну фотографию.
Создание стерео картинки
Как человек воспринимает объем? Чем ближе расположен рассматриваемый объект, тем больше наблюдатель «сводит» глаза. Т.о. если рассматриваемый объект расположен на бесконечно удаленном расстоянии, то глаза будут смотреть на него «параллельно».
Теперь рассмотрим как достигнуть иллюзию объема на плоской картинке. Итак, у нас имеется человек с двумя глазами (рис.1): левый глаз O1 и правый O2,а так же плоскость проекции стерео изображения D1D2. Пусть рассматриваемый объект B расположен на расстоянии h от наблюдателя. Тогда для того чтоб «увидеть» его на картинке необходимо совпадение рисунка в точках B1 и B2. Получается мы держим перед собой плоский рисунок и смотрим как бы «сквозь» него. Левый глаз видит точку B1, правый B2, изображения для них на листе совпадают и создается иллюзия того, что на самом деле мы видим объект B, расположенный за плоскостью листа. Т.о. чем больше расстояние между точками B1 и B2,в которых совпадает изображение, тем «дальше» воспринимается объект B.
Пожалуй теории пока достаточно, можно перейти к практике. Для этого понадобится Photoshop и 3dsMAX. В Photoshop’е создадим текстуру, из которой в последствии будет построено стерео изображение. Несколько рекомендаций: чем больше на текстуре деталей, тем лучше получиться окончательный вариант (с однотонными вообще ничего не получиться); высота текстуры должна совпадать с высотой изображения (поэтому сразу надо определить размер финального стерео изображения); а ширина зависит от того, где вы собираетесь в дальнейшем использовать полученную картинку. На рис.1 величина d_max как раз соответствует ширине текстуры, поэтому в реальности (на экране монитора или после распечатки) она не должна превышать расстояния между глазами a. В тоже время чем больше пикселей по ширине будет в исходной текстуре, тем более качественным получиться окончательный результат. У меня получилась вот такая текстура:
Ширина ее 100 пикселей, а высота 600 (в итоге рассчитываю получить стерео изображение размером 800 на 600 пикселей). Хотя лучше сделать ее так, чтоб она тайлилась по горизонтали. Далее создаем или открывает любой 3D-объект в MAX’е. Я для этого использовал модель осы:
Для результата не пригодятся ни материалы, ни сторонние рендеры, ни источники света. Поэтому если все это имеется в сцене, то назначаем на все стандартный материал, удаляем все источники света и используем Default Scanline Renderer. Теперь можно приступить к написанию скрипта. Для этого в меню Max’а выбираем MAXScript->New Script и откроется окно редактирование скриптов. Наш скрипт будет иметь свой собственный интерфейс. Это можно реализовать двумя способами: на панели Utilites или в отдельном окне. Выберем первый вариант и создадим новую скрипт-утилиту:
utility stereoImg «Stereo Image»
— утилита создания стерео изображения
Сохраним ее с названием stereoImg.ms и отправим ее на просчет. Для этого надо в меню редактора скриптов выбрать Tools->Evaluate All или нажать комбинацию клавиш Ctrl+E. После этого наша утилита приобрела свой интерфейс (рис.4) и единственное что можно с ней сделать – это открыть и закрыть.
Итак, список необходимых элементов: две группы Texture и Render. В группе Texture имеется метка, в которой будет отображаться информация о текстуре, и кнопка, запускающая диалог открытия файла с текстурой. В группе Render – спиннер (определяет ширину рендера), метка (информация о высоте рендера), спиннер (качество стерео изображения), индикатор процесса, кнопка выбора объекта и «самая главная» кнопка запускающая скрипт на просчет. Для этого в тело утилиты надо добавить следующие строки:
group «Texture:»
group «Render:»
В самом начале тела утилиты (перед описанием пользовательских элементов) определим локальные переменные, необходимые для создания стерео изображения:
— определение локальных переменных
Осталось прописать обработчики событий от элементов пользовательского интерфейса. Описание всех событий должно быть следующим образом: on do( ). Для начала опишем поведение MAX’а на нажатие кнопки загрузки текстуры. Что должно происходить: открыться окно диалога выбора файла, после выбора файла текстуры она загружается в MAX, выводиться на форму информация о размере текстуры и ее название, далее инициируются локальные переменные и настраиваются глобальные параметры рендера.
on b_T_img pressed do
height = T_img.height
l_R_h.caption = «height:» + height as String
renderHeight = height
Определим вид, который мы желаем получит на стерео изображении. Для этого нам понадобиться камера. Если в сцене уже имеются камеры с «нужным» видом – отлично, можно использовать их. Если нет, то необходимо создать камеру. Проще всего перейти к виду Perspective, где выбрать необходимый ракурс. После чего создать камеру из вида: в главном меню Create->Cameras->CreateCameraFromView или Crtl+C. Вспомним теорию, там были такие параметры как H – расстояние до максимально удаленного объекта и h_max – расстояние от плоскости проецирования до максимально удаленного объекта. Чтоб не вводить их вручную, будем брать их из свойства камеры, а именно из Clipping Planes. Выберем необходимую камеру, на панели Modify раскроем свиток Parameters, ставим галочку возле Clip Manually. Осталось только настроить Near Clip и Far Clip. Плоскость Near Clip соответствует плоскости проекции стерео изображения, а Far Clip – расстояние до максимально удаленного объекта. Рекомендации: объекты, по которым будет строиться стерео изображение, должна располагаться между Far Clip и Near Clip, Near Clip равно приблизительно половине Far Clip, объекты должны быть расположены подальше от Near Clip и вплотную к Far Clip. Хотя можно этим пренебречь и в дальнейшем экспериментировать с Clipping Planes, для получения более желаемого результата. Т.о. вид настроен, осталось «объяснить» скрипту, что мы будем работать с этой камерой, для этого напишем обработчик нажатия кнопки выбора камеры:
on pb_R_cam picked cam do
После этого ссылка на камеру содержится в pb_R_cam.object.Так же необходимо скрипту отреагировать на изменение пользователем ширины рендера:
on s_R_w changed val do
— обработка изменения ширины рендера
width = s_R_w.value
renderWidth = width
Осталось обработать последнее событие – нажатие «самой главной» кнопки. Опять придется заняться теорией на основе полученной ранее формулы: d/(h-H+h_max))=a/h. Здесь a, H и h_max – констаны. Последние две получаються из Clipping Planes камеры. Определим a, для этого подставим вместо h величину H – крайний случай, когда объект находиться на максимальном расстоянии. Отсюда a=d_max*H/h_max. И последняя формула: d=a*(h-H+h_max)/h – по ней вычисляется расстояние между точками d, изображения в которых совпадают, для того чтоб создавалась иллюзия, что рассматриваемый объект расположен на расстоянии h от наблюдателя.
on b_R_stereo pressed do
— просчет стерео изображения
DOF_img = render camera:pb_R_cam.object outputwidth:width outputheight:height channels:#(#zDepth)
— создание битмапы для будущего стерео изображения
OUT_img = bitmap (width+d_max) height color:black
— заполнение первой полосы текстурой
for x = 0 to (d_max—1)do
for y = 0 to (height—1) do
prb_R_status.value = 0
— отрисовка стерео изображения
— построчное построение стерео изображения
for y = 0 to (height — 1)do
for x = 0 to (width — 1) do
— берем из рендера глубины расстояние от камеры до ближайшей точки
dist = — (getChannel DOF_img [x,y] #zDepth)[1]
prb_R_status.value =(100 * y / height) as integer
prb_R_status.value = 0
Потом идет построчное сканирование канала глубины (с проверкой на то, чтоб расстояние не превысило Far Clip камеры). На основе этой величины h (в скрипте dist) и полученных ранее формул вычисляется расстояние между повторяющимися пикселами. Таким образом идет построение стерео изображения, попутно обновляется прогресс вычислений. И в конце концов на экран выводиться окончательный результат (рис.7).
Ниже приведен полный листинг скрипт-утилиты с некоторыми улучшениями:
utility stereoImg «Stereo Image»
— утилита создания стерео изображения
— определение локальных переменных
group «Texture:»
group «Render:»
on b_T_img pressed do
height = T_img.height
l_R_h.caption = «height:» + height as String
renderHeight = height
on pb_R_cam picked cam do
on s_R_w changed val do
— обработка изменения ширины рендера
width = s_R_w.value
renderWidth = width
on b_R_stereo pressed do
— просчет стерео изображения
if (height == undefined) or (width == 0) then
messageBox «No texture or invalid size»
return 0
if pb_R_cam.object == undefined then
messageBox «Pick camera first»
return 0
DOF_img = render camera:pb_R_cam.object outputwidth:width outputheight:height channels:#(#zDepth)
— создание битмапы для будущего «расширенного» стерео изображения
— причем ширина умножается на точность
OUT_img = bitmap ((width+d_max)*prec) height color:black
— заполнение первой полосы текстурой
for x = 0 to (d_max—1)do
for y = 0 to (height—1) do
for i = 0 to (prec—1) do
c2 = (getPixels T_img [x+1,y] 1)[1]
if c2 == undefined then c2 = (getPixels T_img [0,y] 1)[1]
prb_R_status.value = 0
— отрисовка «расширенного» стерео изображения
— построчное построение стерео изображения («расширенное»)
for y = 0 to (height — 1) do
for x = 0 to (width — 1) do
for dx = 0 to (prec — 1) do
— берем из рендера глубины расстояние от камеры до ближайшей точки (тут тоже идет линейное сглаживание)
dist = (- (getChannel DOF_img [x,y] #zDepth)[1]*(prec—dx) — (getChannel DOF_img [x,y] #zDepth)[1]*dx)/prec
prb_R_status.value =(100 * y / height) as integer
prb_R_status.value = 0
— получение из «расширенного» «нормальное» стерео изображение
for y = 0 to (height — 1) do
for x = 0 to (width + d_max — 1) do
c = black
for i = 0 to (prec—1) do
prb_R_status.value =(100 * y / height) as integer
prb_R_status.value = 0
Изменение здесь только в алгоритме просчета стерео изображения. Добавилась проверка «от дурака»: просчет не начнется, если не была выбрана текстура и камера. Так же тут был реализован алгоритм «улучшенного» расчета стерео изображения с использованием спиннера «качество». В двух словах в чем это заключается: изображение сначала линейно растягивается и просчет ведется тоже «растянуто», а потом полученный результат сжимается до первоначального размера. Разницу можно увидеть на рис.7, рис.8, рис.9.
На рис.7 качество выставлено в единицу, а на рис.8 и рис.9 – 4 и 8 соответственно. Конечно чем выше качество, тем больше время просчета.
Вот и все. Теперь у нас имеется скрипт-утилита, с помощью которой можно из любого 3D-объекта получить стерео изображение. Очень надеюсь что урок был понятен (для этого надо дружить с геометрией 🙂 и полезен (по крайней мере тем, что можно действительно посмотреть свои модели «в объеме»).