省型旧形国電の残影を求めて

戦前型旧形国電および鉄道と変褪色フィルム写真を中心とした写真補正編集の話題を扱います。他のサイトでは得られない、筆者独自開発の写真補正ツールや補正技法についても情報提供しています。写真補正技法への質問はコメント欄へどうぞ

リニアで内部画像処理を行うべきか?

 先日 GIMP を使って、空などのほこりを一挙に消す方法について記事を書きました。このマスクを作る過程がちょっと面倒なので ImageJ 上のプラグインスクリプトで作ろうと思い立ち、今取り組んでいます。

 本来なら GIMP 上のプラグインスクリプトとして作る方が望ましいのですが、Python-fu を使ってスクリプトを書くと、プレビューを表示してから適用することができません。厳密に言うとできないことはないのですが、gimpfu の機能を使ってプレビューさせることはできず、GTK2 を直接たたいてダイアログなどを作らなければならず非常に大変です。しかも GIMP 3.0 で Phthon-fu の仕様が大幅に変わってしまうので、いずれ大幅な書き換えは避けられないので、今の時点であまり深入りしたくありません。

 ただ、ImageJ のプラグインとして書き始めて、はたと気づきました。マスク作成結果が GIMP と同じになりません。しかも GIMP の方が結果が良いです。

 結局この理由は、現在の GIMP 2.10.x は、sRGB など視覚的 TRC がかかった画像を扱っても、内部的にはリニア 32bit RGB色空間で処理しています。

yasuo-ssi.hatenablog.com

しかし ImageJ では、TRC がかかった状態でそのまま計算を行うので結果が異なってしまいます。ということはリニア画像に直した方が良い結果が得られるということ...?

 ただ、以前相対RGB色マスク作成ツール開発時に、リニア画像を扱ってみましたが、非リニア (視覚的 TRC がかかった) 画像よりも、良いマスクができなかった記憶があります。

 ただ、再度考え直してみると、その時は、リニアで処理した画像を、カラーマネジメントのない状態で、そのまま見ていました。GIMP では、非リニアな画像を扱っていても、内部処理に関してはリニアで処理して、ディスプレイの際は再度非リニアに直してモニタに出力しています。そのため、GIMP では明るさを、0 -100 の範囲だとした場合、50 から 60 に、10に引き上げたとしても、実際にはそれに ガンマ 1/2.2 (近似値) を適用しリニアに直した値 (約6.3) を使って引き上げます (なお sRGB 上 10 引き上げ/引下げを行うとしても、リニアで計算する場合は、元の明るさの値がいくつになるかで、実際の引上げ/引き下げ量は変わります)。しかし表示の際はその結果に対し再度ガンマ2.2 を適用した結果を表示しています。

 ImageJ でも同様に処理すれば、リニアで処理すると、より良い結果がでてくるかもしれません... と思いついたところで、ちょっと試してみました。

 まずオリジナルのほこりのついた画像です

オリジナル

 これの上にガウスぼかしを掛けたレイヤーをのせ、それに対し、非リニアのまま計算させて作成したマスクを掛け補正した結果です。

非リニア空間のまま作成したマスク補正結果

 ほこりが薄くなっていますが、消え方は不十分です。

 それに対し、一旦リニアでマスクを作成し、それを再度非リニアに戻したマスクを掛けた結果です。これはほぼ GIMP での処理と等価な処理を行っているはずです。

内部リニア処理で作成したマスクを使った補正結果

 ほこりが完ぺきではないにしろずっと薄くなっています。あくまでも一例にすぎませんが、やはり、非リニアを、内部的に一旦リニアに戻して計算処理を行い、最後に再度非リニアに戻す、という処理を行うことで、より良い画像処理ができるようです。

 GIMP だけでなく ART や darktable などでも同様の処理を行っているはずです。こういうのを見ると、ART が L*a*b 色空間で行う処理を大幅に簡略化している理由もよく分かります。

 上の図ではまだうっすらとほこりの影が残っていますが、このマスクをレベル補正を使い、マスクのホワイトポイントを下げることで、さらにきれいに補正ができます。