8

私は現在、写真からのビデオプロジェクトで立ち往生しています。

問題 :

バグのため、UE4 から画像を抽出しています。スクリーンショットのレンダリング中にすべてのライトが考慮されるわけではありません。出力は HDR 画像です。最初の露出のように、エクスポートされた画像が非常に暗いため、明るさを改善したいと考えています。

ここに画像の説明を入力

UE4 で「露出バイアス」パラメータを使用すると、シーンの明るさを十分に調整できますが、このパラメータをスクリーンショットのレンダリングに適用することはできません。 ここに画像の説明を入力

試行:

Tonemapper アルゴリズムを使用すると (具体的cv::TonemapDragoには)、より良い画像結果を得ることができます: ここに画像の説明を入力

私の場合、トーンマップアルゴリズムの主な問題は、領域の明るさに応じてグローバルな明るさが変化するためです。2番目の画像では、ウィンドウが多くの光を追加するため、アルゴリズムはすべての明るさを低くして平均を調整します. レンダリングされたビデオでは、光の変化は非常に残忍です。

明るさと彩度を変更しようとしましたが、成功しませんでした。アルゴリズムのいくつかのステップTonemapDragoで定数を使用しようとするコードを修正しました。

質問 :

HDR画像から「露光時間を選択」したいです。トーンマップは、同じ画像の複数の露光時間に基づいていますが、私の場合は興味深いものではありません。

他のアイデアは大歓迎です。

編集

CV::マットの深さは 5、タイプは CV_32FC3

cout << mat.step19200ください

私の問題を解決するために使用する2つのサンプルを次に示します。

最初の画像

光窓のあるイメージ

編集2:

gimp で .HDR 画像を開くことができません。イベントは「explosure blend」プラグインを使用しています。Photoshop を使用して十分な結果を得ることができます。その背後にあるアルゴリズムのアイデアはありますか? OpenCV による 6 つのトーンマップ アルゴリズムのいずれかで、露出補正を選択できます。 ここに画像の説明を入力

編集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もコメントで見ました)

4

3 に答える 3

3

Retinexの使用を検討してください。入力に単一の画像を使用し、GIMPに含まれているため、簡単にいじることができ、ソースコードを取得できます(または、とにかく非常に単純です)。写真の代わりにレンダリングがあるため、ノイズがなく、理論的には必要に応じて色を調整できます。

しかし、@mark-ransom が既に述べているように、レンダリングされた出力から情報を復元する際に問題が発生する可能性があります。レンダリング出力として HDR 画像があるとおっしゃいましたが、どういう意味かわかりません。それは単一のRGB画像ですか?各チャンネルの色深度は?サンプルにレティネックスを適用しようとしましたが、明らかに見栄えがよくありません。圧縮と、保存前に適用された範囲の制限のためです。出力の範囲が広く、圧縮されていない場合は、より良い結果が得られます。

編集: 入力に対して retinex を試してみましたが、あまり良くないことがわかりました - 画像の明るい部分 (ランプ/窓) の周りに醜い暗いハローが発生しました。

この場合、単純なトーンマッピングとガンマ補正の方が見栄えがよくなります。cv::pow(exp, 1.0f / gamma, exp);あなたのコードはほとんど問題ありませんでしたが、ちょっとしたタイプミスがありました:v::pow(mapped, 1.0f / gamma, exp);

私はあなたのコードをいじりましたが、このトーンマッピングが彩度を低下させているように見えることに気付きました。これを克服するために、HSV イメージの V チャネルでのみ実行します。自分で結果を比較してください (左 - フル スペース トーンマッピング、右 - 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;
}
于 2015-12-17T15:11:27.577 に答える
0

現在、どのようなシーン照明を使用していますか? 電球がある場所にポイント ライトを使用しているように見えますが、十分な明るさ​​ではありません。レンダリングされていないシーンでは、シーンは完全に明るくなります。レンダリングされたシーンでは、暗くなります。

シーン全体に常にある程度の光が当たるように、少なくとも最小限のスカイライトをお勧めします (実際の暗闇の領域がない限り)。

于 2015-12-17T14:51:43.503 に答える
0
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;
}

このアルゴリズムは、HDR で露出バイアスをシミュレートしようとするトーンマッパーです。openCv 3.0 で使用する場合は、imread の最後の引数として -1 で開くことを忘れないでください。cv::Mat img = cv::imread("mypicture.HDR", -1);

ここに画像の説明を入力

于 2015-12-17T19:43:30.900 に答える