Какой алгоритм я могу использовать для имитации боке?

Я пытаюсь написать сценарий, который перебирает каждый пиксель на фотографии и применяет боке к изображению в целом.

Я создал скрипт на основе этой ссылки , однако это похоже на взлом.

У меня есть три входных изображения: черно-белая карта глубины, фотография и изображение «кисти» боке (которое в настоящее время является шестиугольником). Для каждого пикселя фотографии я накладываю кисть боке так, чтобы она находилась в центре этого пикселя и имела цвет этого пикселя.

Это выглядит... хорошо на крошечных кистях для боке, но как только я увеличу размер кисти для боке, это в конечном итоге будет выглядеть как размытие по Гауссу. Вот картина временного квадрата, размытая моим алгоритмом:

введите описание изображения здесь

Не обращайте внимания на темные края, я могу это исправить.

Вы можете сказать, что он отличается от гауссового, но он все еще далек от того, что можно было бы с уважением назвать боке, с четкими краями:

введите описание изображения здесь

Я понимаю, почему мой алгоритм делает то, что он делает... как мне более точно имитировать боке?

@Imre Я понимаю разницу и то, что боке обычно создается объективом, а гауссовское - постобработкой, но я хочу смоделировать боке.
@Entity: Как мне найти примеры изображений с точной картой глубины? Ваш точен? Я хотел бы попробовать это сам (после финала). Может быть, я придумаю ответ через пару недель тогда. Если ваш общедоступный, можно ссылку на него?
@MartijnCourteaux Для моего первоначального тестирования я просто использую плоскую карту глубины, чтобы все было размыто. Для простой геометрии (например, чашка на столе) было бы довольно просто сделать красивую карту глубины. Для более сложных изображений вам, вероятно, понадобится настоящая карта глубины. Это можно рассчитать по двум изображениям или даже по одному вашему изображению .

Ответы (2)

Я думаю, что основная проблема связана с динамическим диапазоном, ваш алгоритм, вероятно, правильный, но вы работаете с неправильным типом данных.

Точечный источник света, который в противном случае обрезался бы и стал чисто белым, распространяется на большую площадь из-за расфокусированной линзы, так что он образует диск, который не такой яркий и, следовательно, не обрезается.

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

Что у вас есть в реальной цепочке изображений:

bokeh (from the lens) -> digitisation (clipping) -> gamma correction & dynamic range compression

То, что вы делаете, это

sharp image -> digitisation (clipping) -> gamma correction & dynamic range compression -> bokeh simulation

Вы не получите правильный результат, потому что вы не работаете с линейными данными.

Что вы можете сделать, так это попытаться линеаризовать данные, заменить любой динамический диапазон, который был потерян из-за обрезки, выполнить моделирование боке, а затем повторить нелинейные операции!

Вот пример. Я начал с HDR-изображения, которое было подвергнуто тональной компрессии, что дало очень нелинейный результат. Это худший тип изображения для имитации боке!

Выполнение стандартной операции свертки для имитации боке (с использованием инструмента размытия объектива в Photoshop) дает следующий результат, который очень похож на то, что вы получаете:

Чтобы получить лучший результат, я применил экстремальную кривую, чтобы попытаться вернуть изображение примерно к тому, каким оно было бы до тональной компрессии, где блики намного ярче, чем остальная часть изображения. Я сделал это с помощью инструмента уровней, сдвинув центральный ввод далеко вправо, от 1,0 до примерно 0,2). Затем я применил инструмент размытия линзы, как и раньше. Наконец, я применил крайнюю кривую в направлении, противоположном первой кривой. Результат, хотя и далек от идеального, гораздо больше похож на настоящее боке объектива:

 

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

tl; dr, даже если вы реализовали идеальную математическую модель боке, ее необходимо применять к необрезанным линейным данным. Если вы примените те же вычисления к сильно измененным данным (даже стандартный JPEG камеры сильно изменен с математической точки зрения), вы получите совсем другой результат.

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

Другая возможная причина, по которой ваши края могут быть нечеткими, заключается в том, что края вашей маски не острые. Анимация на странице, которую вы предоставили в качестве ссылки, может быть неправильно понята, поэтому в маске исходный пиксель яркий, а другие постепенно темнеют. Это также приведет к размытым краям в расчетном боке. В фотографии диафрагмы имеют определенные края, а не постепенные. Таким образом, на самом деле большинство пикселей в маске должны иметь одинаковую яркость, и только края (где меньше пикселя должно быть окрашено для плавной линии) могут иметь некоторый оттенок серого.

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

При условии, что все операции являются аддитивными, вы не столкнетесь с проблемой распространения темных областей. Это правда, что вам нужна четкая маска, чтобы получить четкие круги, но основная проблема заключается в том, что его операция боке применяется к нелинейным данным.