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

戦前型旧型国電および鉄道と変褪色フィルム写真を中心とした写真補正編集の話題を扱います。写真補正技法への質問はコメント欄へどうぞ

フリーのGIMP用褪色ポジフィルム復元プラグインを発見

 以前、赤色化した褪色ポジフィルムはどの程度復元可能かというのをVuescanや、スキャナドライバ付属のDigital ROCを使ってお見せしたことがあります。ただ、これらはいずれも有料のツールです(スキャナドライバはスキャナを買えば付属しますが...)。しかも現在 Digital ROCは入手できなくなっています。スキャナでもDigital ROCをドライバに組み込んでいるものは、現在市販されていません。

 しかし、フリーウェアでこれらに匹敵するか場合によっては上回りそうなツールを発見しました。Geoff Daniell氏が作成したGIMP用のプラグイン、およびPyhtonスクリプトです。WindowsおよびAndroid用のバイナリーもあります。多分日本人でこれに気づいている人は誰もいないのではないかと思います。因みに、GIMP Scripts.netには掲載されていません。

 これらをダウンロードできるのは以下のサイトからです。

www.lionhouse.plus.com このページの、Software for restoring faded photographs というリンクをクリックしてください。

 また、下記からもダウンロードできますが、本家とはリビジョンが微妙に異なりコードも冗長です。

github.com

 GIMPプラグインは Restore1, Restore2, Restore3 と三種類ありますが、Restore2と3は基本的に同じアルゴリズムを使っており、Restore1のみが異なったアルゴリズムを使っています。

 

 Restore1は、作者の書いたドキュメントによりますと、基本的には、染料が経年変化によって褪色した分を、RGB値をブーストして補償して補正するモデルを考え、具体的には pdb.gimp_levels プロシジャーを使って、RGBの最大値を255にそろえ、またRGBの下から1/10の値を3チャンネルともそろえるということを行っているようです。それに更に微調整を加えています。

 Restore2, 3に関しては、RGB値を一旦LUV色空間の値に変換し、色の全体の平均がニュートラルグレーになるよういろいろとパラメータを調整して各色の値を変更するということを行っているようです。

 Restore1, 2は、変換にインデックスカラーを使っているので、基本的には8bit対応です。但し、Restore1に関しては、試したところ出力は8bitになりますが、16bitの画像でも変換できました。Restore2に関しては、16bit画像に適用すると、bit深度が違うとGIMPに怒られてしまいます。Restore3は2と基本的には同じアルゴリズムを使っていますが、3はインデックスカラーを使っていませんので、16bitの画像に適用すると、16bitの出力画像になります。但し、Restore3はテンポラリーファイルにデータを書き出していますがオリジナルはLinuxで開発されており、Windows上 (あるいはMacOSも同様か) のGIMPで走らせるにはテンポラリーファイルの設定をWindows用に書き換えないと走りません。

 

 GIMPプラグイン以外に単独のPythonスクリプト版があり、これはRestore3と4があります。この両者はアルゴリズムの基本原理は同じようですが、使用するライブラリや、一旦補正した後の調整アルゴリズムの基本原理は同じようですが、使用するライブラリや、一旦補正した後の調整アルゴリズムが異なります。またRestore4に関してはWindowsAndroid版のバイナリーも用意されています。作者のコメントではRestore4が今までのどれよりも変換結果が良好だとのことです。対応ファイルはjpegとなっています。

 Restore4を試してみましたが、Pythonスクリプト版、Windowsバイナリー版共に、ファイルのピクセル数が大きい画像は変換してくれません。2Kぐらいの画像なら問題なく変換してくれますが... GIMPプラグイン版の方はそのようなことはなく、大きくても変換してくれます。

 で、実際の変換結果ですが、以前褪色ポジフィルムのサンプルとして掲げた以下の画像を変換してみます。

f:id:yasuo_ssi:20201106220511j:plain

オリジナル

 まずこれをRestore1を使って、16bitファイルから変換した結果です。

f:id:yasuo_ssi:20210202224127j:plain

Restore1 from 16bit TIFF

 次は、Restore1で8bitのJpegファイルから復元した結果です。

f:id:yasuo_ssi:20210202224234j:plain

Restore1 from 8bit Jpeg

 そしてRestore2で8bit Jpegファイルからの復元結果です。

f:id:yasuo_ssi:20210202224512j:plain

Restore2 from 8bit Jpeg

 そして、Restore3を使って16bit画像から復元した結果です。

f:id:yasuo_ssi:20210202224804j:plain

Restore3 from 16bit TIFF

  Restore4を使って8bit Jpegファイルからの変換結果です。

f:id:yasuo_ssi:20210202230440j:plain

Restore4

 Restore4が成績が最も良いのは間違いありませんが、Restore3の結果をホワイトバランス調整に掛ければRestore4に行きそうな気がします。またGIMPプラグインとして使え、ファイルの大きさの制限もないのはRestore3のメリットです。

 また、Restore1は、このサンプルの場合、やや不自然な感じではありますが、元ファイルの撮影状況や褪色状況によっては、Restore1のアルゴリズムの方がうまくいくケースもありました。Restore1と 2,3ではどちらのアルゴリズムが優れているというよりも、ファイルの状態 (元画像や褪色状況) によっていろいろ使い分けたら良いように思います。この差の原因として一つ考えられるのは、Restore2, 3では、すべての色の平均を取るとニュートラルグレーになるという仮定が導入されていますが、その仮定が不適切な画像は、2, 3では1よりも好ましい結果を得られない、という可能性です。

 なおRestore2は3で代替可能です。Restore2は8bitしか対応していないので、Restore3をダウンロードするだけで良いでしょう (但しRestore2の方が計算速度は速いです)。

 

 ちなみに以前お見せしたVuescanによる補正結果です。

f:id:yasuo_ssi:20201106220539j:plain

Vuescan 退色補正+色の復元 from 16bit Raw

 Vuescanの方がナチュラルで落ち着いています(やや地味とも感じられます)が、Restore3, 4もフォトレタッチソフトを使ってもうちょっと手を加えれば、ここまで行きそうです。またこれは16bitからの変換でしたが、8bit Jpegからの変換は成績が良くありませんでした。

f:id:yasuo_ssi:20201107083403j:plain

8bit Jpegファイルを取り込み Vuescanで補正

 これを考えると、8bitのJpegからの変換でもそこそこ行けますので、かなり強力な補正ツールだと言えそうです。しかもフリーで公開してくれています。

 ところで、上記のダウンロードサイトからどのようにGIMPにインストールするかですが、上のサイトへ行きGIMP Pluginsフォルダへ行きます。すると以下のプラグインが並んでいます。

Restore1.py, Restore2.py, Restore3.py, Batch_Restore1.py, Batch_Restore2.py, Batch_Restore3.py

 頭に Batch がついているプラグインは、フォルダを指定すると、そのフォルダ内の Jpeg 画像をすべて変換するプラグインです。

 そこで、使いたいプラグインをクリックします。個人的には、Restore1と3だけで良いのではないかと思いますが、お好みで。するとプラグインソースコードが現れます。そのソースコードの全文をコピーし、テキストエディタ等に貼り付けます。その際、改行コードを指定できるテキストエディタを使ってください。貼り付けたら、改行コードにLFを指定し、所定の名前で保存します。保存したプラグインファイルを、GIMPプラグインインストールフォルダにコピーします。

Windowsの場合。GIMPプラグインフォルダは以下です。

C:\Users\%username%\AppData\Roaming\GIMP\2.10\plug-ins

(特定のユーザのみ使えるようにする場合)

または、

C:\Program Files\GIMP 2\lib\gimp\2.0\plug-ins

(どのユーザでも使えるようにする場合)

プラグインをインストールするとGIMPのメニューに restoreという項目が現れ、そこから実行することができるようになります。

 Restore1, 2.pyはおそらくそのまま使えると思いますが、Restore3.pyは、Linux以外のシステムの場合、作業用一時ファイル保存フォルダを指定しなおさないとちゃんと走りません。そこでそれを書き換えます。書き換えるべき場所は 以下の場所です。

# place where gimp stores levels data and debug file   ←コメント行
gimp_levels_location = "/home/gjd/.gimp-2.8/levels/restore"
debug_file_location = "/home/gjd/gimp/NewRestore/debug.txt"

 

これを私の場合(windows)は以下のように書き換えました。

gimp_levels_location = "C:\Users\%username%\AppData\Roaming\GIMP\2.10\levels\restore"
debug_file_location = "C:\Users\%username%\AppData\Roaming\GIMP\NewRestore\debug.txt"

上の、%username%のところは、windowsにログオンする際の実際のユーザ名が入ります。同時に、

C:\Users\%username%\AppData\Roaming\GIMP\2.10\levels\restore

C:\Users\%username%\AppData\Roaming\GIMP\NewRestore

という二つの一時ファイル格納用フォルダをあらかじめ作っておきます。あるいは c:\temp というような一時フォルダを作って、それを指定しても良いと思います。また、当然ながら、GIMP起動前にここで指定したフォルダをあらかじめ作っておかないとエラーが発生し、途中でストップします。

 

 またRecovery1.pyは、GIMPがまだ8bit画像しか扱えなかった時代に開発されたものです。このため、8bitにしか対応していなかったり、廃止予定である gimp_levels というプロシジャーを使っています。このプロシジャーは、0-255の値でパラメータを与えていますが、GIMPが8bit以外の画像に対応するようになって、時代遅れになっています。

 これらの問題を解決するには、次のように書き換えます。

まず、出力ファイルが8bit以外にも対応させるため、オリジナルファイル 115行目、

  new_image = pdb.gimp_image_new(width, height, 0)

を以下のように書き換えます。

  imgprecision = pdb.gimp_image_get_precision(image)
  new_image = pdb.gimp_image_new_with_precision(width, height, 0, imgprecision

これにより、元イメージと同じ画像色深度の出力ファイルとなります。gimp_image_getprecision は、画像のbit深度を取得するプロシジャーです。また、gimp_image_new_with_precision 、はbit深度を指定して新しい画像を作成するプロシジャーです。gimp_image_new だと、8bit画像しか作れません。

 なお、スクリプトにはもう一カ所、gimp_image_new を使っているところがありますが、こちらは、パラメータ計算用に、オリジナルサイズの1/10の作業用インデックス画像を作成するために使うので、8bit固定で大丈夫なため、書き換える必要がありません。

 これに合わせて、220行目も以下のように書き換えてください。

(旧)  pdb.gimp_layer_set_mode(layer_d, 15)
   ↓
(新)  pdb.gimp_layer_set_mode(layer_d, LAYER_MODE_DIVIDE)

 gimp_layer_set_mode プロシジャーは、レイヤーを重ねるときに、下のレイヤーに対してどのモードで重ねて表示するかを指定するプロシジャーです。最初のパラメータは、対象となるレイヤー、2番目のパラメータは重ねて表示するモードを指定します。オリジナルは、15となっていますが、これは除算モードという意味です。しかし、この値が15だと、LAYER_MODE_DIVIDE_LEGACY となり、8bit画像を前提とした除算モードになります。しかし、出力ファイルが8bitでない可能性があるように前のコードを修正しましたので、こちらも LAYER_MODE_DIVIDE を指定します。もし数値で指定するなら、 LAYER_MODE_DIVIDE  と記入する代わりに 41 と指定します。

 さらに、廃止予定の gimp_levels  ついては、今 (Ver. 2.10で) は走りますが、将来的なことを考えると、後継プロシジャー gimp_drawable_levels に書き換えた方が良いです。具体的にはオリジナルの 23, 122, 186行目を次のように書き換えます。

既存

  pdb.gimp_levels(layername, C + 1, 0, m[C], alpha[C], 0, 255)

書き換え

  pdb.gimp_drawable_levels(layername, C + 1, 0, float(m[C])/255, TRUE, alpha[C], 0, 1.0, TRUE)


 上の、layername は、場所によって slayer だったり layer0 になっているので、場所に応じて適宜変えてください。

 

 既に、褪色補正のための有償ツールを使っている方もおられると思いますが、画像の褪色度合い、さらに元の画像も一様ではないので、一つのアルゴリズムのみが正解とは限りません。代替アルゴリズムがあると、いつものツールではうまくいかない場合でもうまくいくかもしれません。このツールは無料ですので持っていても損はないと思います。