豪鬼メモ

一瞬千撃

擬似HDR現像

Web現像ツールgenzo.cgiがさらにパワーアップ。擬似HDR現像ができるようになった。1枚のRAWデータから、露出を変えた撮影を模した3枚の画像を現像を現像し、それを合成して仕上げる。すると、あら不思議、連写合成したHDR写真みたいな鮮やかで見やすい画像が出てくる。
f:id:fridaynight:20181201042103j:plain


本題に入る前に、細かい更新についてお知らせ。まずはデモサイトをご覧いただきたい。自動現像の弱みとして、作画意図を汲んだ適正露出が何かが機械的には分からないので、理想より暗い画像や明るい画像が出て来てしまうという問題があった。そこで以前のバージョンでは普通と暗めと明るめの三つの画像を出力してユーザに選んでもらうようにしていたのだが、ちょっとダサいし遅いので、その方法は廃止した。その代わりに、手動で補正値を設定できるようにした。最新バージョンでは、以下の設定項目を変えることができる。

  • Interpolation: 画素補完(デモザイク)のアルゴリズム。Halfが畳み込み、Bilinearがバイリニア補完。他にVNGとPPGとAHD。
  • CA Correction: 倍率色収差の補正。Manualにすると赤チャンネルと青チャンネルの任意の倍率が設定できる。
  • White Balance; ホワイトバランス。Cameraだとカメラの撮影時設定を使い、Autoだと画像から自動判定し、Manualだと各チャンネルの係数を設定できる。
  • Level: レベル補正。Autoだとダイナミックレンジいっぱいになるように自動設定され、As-isだと何も行わず、Manualだとブラックポイントとホワイトポイントを設定できる。
  • Brightness: スケール対数補正の投機実行での目標の平均輝度を設定する。Softerが40%、Softが45%、Normalが50%、Hardが55%、Harderが60%。
  • Contrast: 輝度のシグモイド補正の強度。Softerが0.5、Softが1.0、Normalが1.35、Hardが1.5、Harderが2.0。
  • Saturation: 彩度のスケール対数補正の強度。Palerが-0.5、Paleが0、Normalが0.2、Deepが0.5、Deeperが1.0。
  • Pseudo-HDR: 擬似HDRのスケール対数補正の強度。Noneが0、Weakerが1、Weakが2、Mediumが4、Strongが8、Strongerが16。
  • Resizer: 画像のリサイズ。長編のピクセルで指定。

f:id:fridaynight:20181204010607p:plain

Interpolationはベイヤー配列のR、G、G、Bの4つの画素をからどうやってRGB画像を作るかの設定だ。デフォルトのHalfだと、RGGBの各画素を畳み込んで1つピクセルを作るので、画素数が4分の1になる。しかし縮小画像としての解像感は良くなり、ビニング効果でノイズの少ないクリーンな画像になるし、そして処理が単純なので高速だ。普通に補完した画像が欲しい場合には、DcrawのデフォルトであるAHDを使うのがいいっぽい。デフォルトがHalfなのは、Webツールとしては縮小画像が得られた方が使いやすいのと、高速性を重視したためである。大きい画像が欲しい場合にも、最初はHalfでサクサク動作させてBrightness等の他の項目を詰めて、最後にAHDに変えた結果をダウンロードすると楽だ。

パラメータをちょっと変える都度、rawデータをアップロードしていたのでは時間もかかるし通信量も食い過ぎる。なので、一度raw画像をアップロードしたら、内部的にセッションIDを振って、同じデータを再利用できるようにした。genzo.cgiに最初にアクセスした時にはファイルダイアログでraw画像を選ぶのだが、それ以降の操作はファイルに何も設定しないでおくと、直前にアップロードしたデータを使い回してくれる。現像処理結果も同様にキャッシュされるので、以後の操作がかなり高速化される。


さて、HDRの話だ。デモサイトでPseudo-HDRの値を変えて遊んでみてほしい。High Dynamic Rangeとはダイナミックレンジが広いという意味だが、HDR画像と言った場合には二つの意味があることに注意すべきだ。一つはダイナミックレンジの広いデータを32ビットなどの大きい色深度で記録したファイルで、もう一つはダイナミックレンジの広いデータをトーンマッピングしてダイナミックレンジの狭い形式で記録したものである。おそらくHDR写真というと後者のことを指すことが多いだろう。ここでもその意味で用いる。多くの場合、露出を変えた2枚以上の画像を合成して、白飛びしがちな明るい部分は暗い画像からデータを取得し、黒潰れしがちな暗い部分は明るい画像からデータを取得することで、一枚の画像で広いダイナミックレンジを表現できる。最近のカメラだとそのための露出ブラケット撮影と合成処理を一気にやってくれる機能がついていることが多いし、露出ブラケット撮影だけしてLightroomやその他のソフトウェアに取り込んで合成処理を行うこともできる。

今回実装したのは「擬似HDR」とか「ワンショットHDR」とか呼ばれる手法で、raw画像は1枚しか使わない。最近のデジカメのダイナミックレンジは十分に広いので、現像する際にブラックポイント(現像後に輝度0になる入力の輝度値)を上げたり、ホワイトポイント(現像後に輝度65535になる入力の輝度値)を下げたりするのは定石だ。そうしないとコントラストが低くて眠い画像になってしまう。普通にトーンカーブを設定する方法だとそうやって捨てざるを得ない情報も、HDR合成のトーンマッピングの手法を応用するとうまく扱うことができる。1枚のraw画像から、露出アンダーを模して現像した画像と、適正露出で現像した画像と、露出オーバーを模して現像した画像の3枚を生成して、それをHDR合成すればいい。

HDR合成の処理はenfuseというOSSのソフトウェアでできるので、あとは露出を変えた3枚の画像をどうやって作るかだけ考えればいい。適正露出の画像を生成してから、それに対して暗くする変換と明るくする変換を行うことになる。変換の方法には様々な種類が考えられる。線形変換、ガンマ補正、変曲点を変えたシグモイド補正、スケール対数補正が候補として考えられる。それぞれを試した結果、スケール対数補正とシグモイド補正を組み合わせるといい感じになる。ここでは説明を単純化するためにスケール対数補正だけでやってみる。最近何度も述べているが、明るくするには log(1+C*v)/log(1+C) を適用し、暗くするにはその逆関数の (exp(v*log(1+C))-1)/C を適用すればよい。Cには任意の非負の数値を指定して強度を設定できる。

sRGBの画像input.tifがあったとして、こんな風にツールを呼んでいけばHDR画像output.tifが作れる。合成した画像はコントラストが低い眠い画像になるが、それを適当なトーンカーブで調整してやると、画面全域が鮮やかな画像に生まれ変わる。

# 明るい画像を生成
$ convert input.tif -colorspace rgb \
  -evaluate log 8 -colorspace srgb light.tif

# 暗い画像を生成。2.1972はlog(1+8)
$ convert input.tif -colorspace rgb \
  -evaluate multiply 2.1972 -evaluate exp 1 \
  -evaluate subtract 100% -evaluate divide 8 \
  -colorspace srgb dark.tif

# 入力画像と明るい画像と暗い画像を合成
$ enfuse --output=output.tif --depth=16 input.tif light.tif dark.tif

# コントラストの調整。2.0794はlog(8)
$ convert output.tif -colorspace rgb \
  -sigmoidal-contrast 2.0794,48% -colorspace srgb output.tif


スケール対数補正による実例を見てみよう。まずこの画像は、現像した画像を平均輝度50%になるまでスケール対数補正で調整したものだ。
f:id:fridaynight:20181201031027j:plain

そのままだと眠すぎるので、強度9のシグモイド補正でコントラストを上げるとこうなる。子供の顔を適正露出にすると、背景のハイライトが飛んでしまう。本当はもっと子供の顔を明るくしたいが、背景を白飛びさせたくないとするとそれはできない。このように被写体のダイナミックレンジが広いシーンでは、HDR合成がしたくなる。
f:id:fridaynight:20181201031142j:plain

入力画像としては、先に提示した眠い方の画像を用いるのがよい。その方が調整しやすいのだ。まずは明るい画像を作る。明るい画像はシャドウが見やすい。髪の毛の陰の部分まで視認できる。
f:id:fridaynight:20181201031543j:plain

暗い画像も作る。暗い画像はハイライトが見やすい。窓の外の風景も視認できる。露出を下げても白飛びしている部分は、撮影時に飛んじゃってる部分なので、流石に救えないけども。
f:id:fridaynight:20181201032049j:plain

三枚の画像をHDR合成すると、このような画像になる。入力画像と同じく眠い感じだが、画面内の多くの部分の視認性が上がっている。シャドウもハイライトも。
f:id:fridaynight:20181201032414j:plain

仕上げに、強度9のシグモイド補正でコントラストを上げるとこうなる。HDR合成を経ないでコントラストを上げた例よりも、特にハイライト部分の視認性が向上しているのがわかる。
f:id:fridaynight:20181201032650j:plain

効果がわかりやすいように、HDRなし、強度2のHDR、強度8のHDR、強度16のHDRの結果を並べる。強度が上がるほど「濃く」が出る感じ。統計値から言えばコントラストは下がっている(輝度の分散が低くなっている)のに、むしろコントラストが上がっているような錯覚をしてしまう。その点ではPLフィルタの効果に似ている。

f:id:fridaynight:20181201120842j:plain:w150 f:id:fridaynight:20181201120907j:plain:w150 f:id:fridaynight:20181201120941j:plain:w150 f:id:fridaynight:20181201120958j:plain:w150

明るい画像と暗い画像を作るもう一つの方法としてシグモイド補正がある。変曲点を0にしてかければ明るい画像ができるし、変曲点を1にしてかければ暗い画像ができる。その強度はスケール対数補正の強度Cに対して log(C) * 1.35 くらいにすると同じくらいになる。スケール対数補正16による擬似HDRとシグモイド補正3.74による擬似HDRを並べて比較してみよう。タブで開いて画像を切り替えながら見てみると、スケール対数補正の擬似HDRの方がシャドウとハイライトを中間トーンに寄せる効果が高いことがわかる。ハイライトとシャドウの視認性を高める効果がある反面、全体のコントラストが低下して眠い感じになってもいる。一方でシグモイド補正による擬似HDRだと、中間トーンのコントラストを上げつつ、シャドウとハイライトの視認性を維持するという効果がある。どっちも捨てがたい。

f:id:fridaynight:20181203095226j:plain:w300 f:id:fridaynight:20181203095240j:plain:w300

ならば、両方を組み合わせようということになる。スケール対数補正4をかけてから、シグモイド補正1.87をかけて、その結果を擬似HDRで合成するのだ。そうすると、めっちゃ見やすい。元画像が暗かろうが明るかろうが自動的に見やすくなるというのが、自動補正ツールとしては最大の美点だ。
f:id:fridaynight:20181203100623j:plain

GUIの現像ソフトウェアで調整すれば任意のトーンカーブで同じことができるのだが、自動でそれに近いことができてしまうのが擬似HDRの面白いところだ。この例の撮影に使ったOMD E-M10はダイナミックレンジが12EVくらいと、最近のデジカメにしては貧弱な機種だが、それでもそこそこ効果がある。14EVを越える最近の機種だともっと幅広いシーンで擬似HDRを活用できるだろう。

enfuseの実装がどうなっているか知りたいところだが、仕様を読む限りでは結構単純なことをしている。画像を合成するにあたり、その各画素が出力にどの程度貢献するのか、すなわち加重平均の重みを、一定の関数で決めるのだ。デフォルトでは正規分布確率密度関数が使われる。つまり各入力画像において輝度が50%に近い画素はよく貢献し、ハイライトとシャドウはあまり貢献しない。したがって、出力のハイライト部分を生成する時には暗くした入力画像がよく貢献し、出力のシャドウ部分を生成する時には明るくした入力画像がよく貢献するというわけ。genzo.cgiのソースコードについてはここから見られる。


いろんな写真で擬似HDRを試すとどんな感じになるか見てみよう。通常現像、擬似HDR現像の順に並べていく。一瞥して双方が変わらないと思うかもしれないが、だとしたら成功だ。クリックすると大きい画像が見られるが、タブで開いて見比べてみると、実は結構違うのが分かる。

f:id:fridaynight:20181201142302j:plain:w300 f:id:fridaynight:20181029104228j:plain:w300

f:id:fridaynight:20181201142338j:plain:w300 f:id:fridaynight:20181029091426j:plain:w300

f:id:fridaynight:20181201145727j:plain:w300 f:id:fridaynight:20181118091449j:plain:w300

f:id:fridaynight:20181201145816j:plain:w300 f:id:fridaynight:20181111111713j:plain:w300

f:id:fridaynight:20181201145851j:plain:w300 f:id:fridaynight:20181201152335j:plain:w300

f:id:fridaynight:20181201150007j:plain:w300 f:id:fridaynight:20181201153454j:plain:w300

f:id:fridaynight:20181201150039j:plain:w300 f:id:fridaynight:20181201152619j:plain:w300


まとめ。Web現像ツールに細かな改良を加えて、擬似HDR機能をつけた。擬似HDRのおかげで画面全体の視認性が上がるので、見栄えのする仕上げが容易になった。強烈な後処理を施している割には、出てきた画像に不自然さがあまりないというのが美点だ。"HDR写真" でググるといかにもCGって感じの作例ばかりが出てくるけども、私がやりたいのはそうじゃない。直射日光下や逆光の作例でも視認性を維持した現像を簡単にするためのツールが欲しいのだ。今回の実装はそこそこうまくいったと思う。合成加工をしているって言わなければ気づかないくらいでありつつ、かなり見やすい写真が出てくる。