Выберите яркость (экспозицию) из HDR-изображения

В настоящее время я застрял на видеопроекте из фотографий.

Проблема:

Извлекаю картинки из UE4, из-за бага не все огни учитываются при рендеринге скриншота. На выходе получаются HDR-изображения. Я хочу получить лучшую яркость, потому что экспортированное изображение очень темное, как и первая экспозиция.

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

Используя параметр «смещение экспозиции» в UE4, я могу получить действительно хорошую яркость моей сцены, но не могу применить этот параметр к рендерингу скриншота: введите здесь описание изображения

Попытки:

Используя алгоритм Tonemapper (в частности, cv::TonemapDrago), я могу получить лучший результат изображения: введите здесь описание изображения

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

Я пытался изменить яркость и насыщенность без успех. Я изменил код TonemapDrago, пытаясь использовать константы для некоторых этапы алгоритма.

Вопрос:

Я хотел бы «выбрать время экспозиции» из изображения HDR. Тональная карта основана на нескольких временах экспозиции одного и того же изображения, что в моем случае неинтересно.

Любая другая идея приветствуется.

ИЗМЕНИТЬ:

CV::Глубина коврика равна 5, тип CV_32FC3.

cout << mat.step дайте мне 19200

Вот 2 примера, которые я использую, чтобы попытаться решить мою проблему:

Первое изображение

Изображение со светлым окном

Редактировать 2:

Невозможно открыть изображение .HDR с помощью gimp, событие с плагином «explosure blend». Я могу получить достаточно отличный результат с помощью Photoshop. Любое представление об алгоритме, стоящем за этим? Любой из 6 алгоритмов Tonemap от OpenCV позволяет выбрать коррекцию экспозиции. введите здесь описание изображения

ИЗМЕНИТЬ 3:

Я следовал алгоритму, описанному в этом уроке для openGL, который дает этот C+ код мне:

cv::Mat exposureTonemap (cv::Mat m, float gamma = 2.2, float exposure = 1)
{
  // Exposure tone mapping
  cv::Mat exp;
  cv::exp( (-m) * exposure, exp );

  cv::Mat mapped = cv::Vec3f(1.0) - exp;
  // Gamma correction 
  cv::pow(exp, 1.0f / gamma, exp);

  cv::imshow("exposure tonemap", exp );
  cv::waitKey();

  return exp;
}

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

Читая код, что-то не так, потому что 1 и 1 в качестве аргумента не должны изменять изображение. Исправлено, ответ опубликован. Большое спасибо @user3896254 (Ge тоже видел это в комментарии)


person Marcassin    schedule 14.12.2015    source источник
comment
В каком формате выходное изображение? Если у него недостаточно битовой глубины, вы не сможете восстановить потерянные данные.   -  person Mark Ransom    schedule 17.12.2015
comment
@MarkRansom Формат пикселя изображения .hdr, открытый с помощью opencv, — CV_32FC3.   -  person Marcassin    schedule 17.12.2015
comment
Если вы загрузите пример этого изображения куда-нибудь - нам будет легче вам помочь. Вы можете сбросить необработанный буфер изображения в двоичный файл и указать разрешение изображения, чтобы другие могли его использовать.   -  person alexisrozhkov    schedule 17.12.2015
comment
@ user3896254: Готово, я добавил ссылку, думаю, это проще, чем записывать двоичные файлы. я читаю и пробую твой ответ   -  person Marcassin    schedule 17.12.2015
comment
что касается кода для тональной компрессии, который вы добавили - вы должны сделать v::pow(mapped, 1.0f / gamma, exp); вместо cv::pow(exp, 1.0f/gamma, exp);   -  person alexisrozhkov    schedule 17.12.2015
comment
@user3896254 user3896254 Да, я только что это сделал :( Кажется, у меня не работает, я думаю, я опубликую исправление в качестве ответа. Большое спасибо за всю вашу помощь.   -  person Marcassin    schedule 17.12.2015
comment
Поскольку вы не можете назначить награду за свой ответ, может быть, я отредактирую свой ответ с помощью этого исправления, чтобы вы могли его принять? Так как иначе будет потеряно 100 репутации.   -  person alexisrozhkov    schedule 17.12.2015
comment
Если хотите. Мне плевать на репутацию, я все равно хотел найти решение :D   -  person Marcassin    schedule 18.12.2015


Ответы (3)


Рассмотрите возможность использования Retinex. Он использует одно изображение для ввода и включен в GIMP, поэтому с ним легко поиграться, кроме того, вы можете получить его исходный код (или создать свой собственный, что в любом случае довольно просто). Так как вместо фото у вас рендеры - шума нет, и теоретически вы можете настроить цвета под свои нужды.

Но, как уже сказал @mark-ransom, у вас могут возникнуть проблемы с восстановлением информации из обработанного вывода. вы сказали, что у вас есть HDR-изображения в качестве вывода рендеринга, но я не уверен, что вы имеете в виду. Это одно изображение RGB? Какова глубина цвета каждого канала? Я попытался применить ретинекс к вашему образцу, но, очевидно, он выглядит не очень хорошо из-за сжатия и ограниченного диапазона, примененного перед сохранением. Если ваш вывод имеет высокий диапазон и не сжат - вы получите лучшие результаты.

РЕДАКТИРОВАТЬ: я попробовал ретинекс на вашем входе, и это оказалось не очень хорошо - яркие части изображения (лампы / окна) создавали вокруг себя уродливые темные ореолы.

В этом случае простая тональная коррекция и гамма-коррекция выглядят намного лучше. Ваш код был почти в порядке, просто у вас была небольшая опечатка: вместо cv::pow(exp, 1.0f / gamma, exp); у вас должно было быть v::pow(mapped, 1.0f / gamma, exp);

Я возился с вашим кодом и заметил, что это тональное отображение ухудшает насыщенность цвета. Чтобы преодолеть это, я выполняю это только на V канале изображения HSV. Сравните результаты самостоятельно (слева — тональная компрессия полного пространства, справа — только V): введите здесь описание изображения введите здесь описание изображения Обратите внимание на цвет пола, небо в окне и желтоватый свет цвет, который сохранился при таком подходе.

Вот полный код для полноты картины:

#include <opencv2/opencv.hpp>

using namespace cv;

Mat1f exposureTonemap (Mat1f m, float gamma = 2.2, float exposure = 1) {
  // Exposure tone mapping
  Mat1f exp;
  cv::exp( (-m) * exposure, exp );
  Mat1f mapped = 1.0f - exp;

  // Gamma correction
  cv::pow(mapped, 1.0f / gamma, mapped);

  return mapped;
}

Mat3f hsvExposureTonemap(Mat &a) {
  Mat3f hsvComb;
  cvtColor(a, hsvComb, COLOR_RGB2HSV);

  Mat1f hsv[3];
  split(hsvComb, hsv);

  hsv[2] = exposureTonemap(hsv[2], 2.2, 10);

  merge(hsv, 3, hsvComb);

  Mat rgb;
  cvtColor(hsvComb, rgb, COLOR_HSV2RGB);

  return rgb;
}

int main() {
  Mat a = imread("first.HDR", -1);
  Mat b = imread("withwindow.HDR", -1);

  imshow("a", hsvExposureTonemap(a));
  imshow("b", hsvExposureTonemap(b));
  waitKey();

  return 0;
}
person alexisrozhkov    schedule 17.12.2015
comment
Ууу, хорошо, тональная карта на «значении» из изображения HSV дает лучшие результаты. Спасибо за это исправление! - person Marcassin; 18.12.2015

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

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

person Jesse Williams    schedule 17.12.2015
comment
Проблема этой ошибки заключается в том, что некоторые источники света и направленные источники света не учитываются при 360-градусном рендеринге точки обзора в UE. Добавление более яркого скайбокса увеличит количество света из окна, а алгоритм тональной карты будет еще более жестким с движением камеры. Даже при этом извлеченное изображение будет слишком темным, чтобы его можно было использовать «как есть». - person Marcassin; 17.12.2015

cv::Mat exposureTonemap (cv::Mat m, float gamma = 2.2, float exposure = 1)
{
  // Exposure tone mapping
  cv::Mat exp;
  cv::exp( (-m) * exposure, exp );
  cv::Mat mapped = cv::Scalar(1.0f, 1.0f, 1.0f) - exp;

  // Gamma correction 
  cv::pow(mapped, 1.0f / gamma, mapped);

  /*
  cv::imshow("exposure tonemap", mapped );
  cv::waitKey();
  */

  return mapped;
}

Этот алгоритм представляет собой Tonemapper, пытающийся имитировать смещение экспозиции в HDR. Если вы хотите использовать его в openCv 3.0, не забудьте открыть с -1 в качестве последнего аргумента imread cv::Mat img = cv::imread("mypicture.HDR", -1);

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

person Marcassin    schedule 17.12.2015