スクリーントーンを除去しグレースケール化する方法を考える

コンピュータ

高解像度でスキャンした画像の場合、スクリーントーンの点描が、円などの図形としてはっきり認識できることがあります。

スクリーントーンは、点の大きさや点同士の間隔によって明暗の階調を表現しています。
このような画像を、通常のグレースケール画像として表現できないかというのが今回のテーマです。

ちなみに筆者は画像処理の専門家ではなく、趣味の範囲で試行錯誤しているだけです。
この記事もその過程の記録として読んでいただければと思います。

まず最初に重要な点として、

グレースケール画像をスクリーントーン化することは可能ですが、
トーン化された画像を元のグレースケール画像に戻すことは基本的には出来ません。

これは画像処理の世界では不可逆(irreversible)な処理と呼ばれます。

グレースケール画像をトーン化する際には、多くの情報が失われます。
そのため、トーン画像だけから元の階調を完全に復元することは理論的には不可能です。

ただし、高解像度のスキャン画像ではトーンの点が個別の図形として認識できるため、
点の密度やサイズから明るさを推定することはある程度可能です。


不可逆であると言いました。

これは本来、絶対に元に戻すことができないという意味です。
つまり、完全に元の情報を復元することは不可能ということになります。

しかし近年では、この「不可逆」という言葉のニュアンスも、
少し柔らかく捉えられる場面が増えてきました。

機械学習や画像処理の発展により、
完全に元通りではないものの、それらしく復元するということが
ある程度可能になってきているためです。

そして、この不可逆という壁に対して、
風穴を開けるアプローチとして登場したのが機械学習AIです。

機械学習では、大量の画像データからパターンを学習することで、
失われた情報を推測し、「元の画像はおそらくこうであっただろう」
という形で再構成することが可能になります。

もちろん、これは本当の意味で元の画像を復元しているわけではありません。
あくまで統計的な推測による再構成です。

それでも、人間の目で見たときには
「元の画像にかなり近い状態」に見える結果が得られることがあります。

このような発想は、超解像やノイズ除去などの分野ですでに活用されています。
スクリーントーンの除去についても、同様の考え方が応用できる可能性があります。

筆者が試したところ、超解像処理で知られている Real-ESRGAN を
ファインチューニング(追加学習)することで、

スクリーントーン処理された縮小画像から、
グレースケールの高解像度画像を推論することが出来ました。

個人的には、この方法でほぼ問題は解決したと言える状態です。

ただし、これはあくまでファインチューニングによる結果です。

つまり、特定の画像を元に追加学習させたモデルであり、
すべてのスクリーントーンに対して汎用的に対応できるわけではありません。

スクリーントーンには、
線数・角度・点の形状など様々な種類が存在するため、
それらすべてに対応するには、より多様なデータでの学習が必要になります。


機械学習を使う方法は、ある意味チート行為のようなところがあります。
従来型の画像処理フィルターを使ってスクリーントーンを除去する方法も考えてみます。

画像処理だけでトーンを除去する場合、いくつかのアプローチがありますが、
筆者が試した中で最も効果が高かった方法は、単純に画像を縮小することです。

理屈はさておき、トーン処理された画像を近くで見ると、
点描のパターンがはっきりと確認できます。

しかし、少し離れて見るとどうでしょうか。
点描は目立たなくなり、グレースケールの画像のように見えてきます。

これは人間の視覚が、細かい点のパターンを平均化して認識するためです。

そして「離れて見る」ということは、
画像処理の観点で言えば、画像を小さく縮小することとほぼ同じ意味になります。

ただし、画像を縮小するとグレースケールに近い見た目にはなりますが、
その代わりにディテールも失われていきます。

細かい線や模様など、本来残したい情報も平均化されてしまうためです。
そのため、ある程度許容できる範囲での縮小にとどめる必要があります。

ちなみに電子書籍の解像度は、
**高さが1200~1600px程度(B5雑誌サイズ)**が主流のようです。

このあたりの解像度が、
ディテールをなるべく保ちながら縮小する目安になるのではないかと思います。

このレベルまで縮小した画像では、
トーン部分は完全なグレースケールにはならず、
細かい格子模様のようなパターンとして残ることがあります。

次の問題は、この格子模様をどのように処理するかです。


この格子模様を処理する方法として、
次のような手順を試してみました。

まず、ガウシアンフィルターを使って格子模様をぼかします。
これにより、トーン由来の細かいパターンを弱めることができます。

ただし、この処理だけでは画像全体がぼやけてしまいます。
そこで次に、アンシャープマスクフィルターを使い、
ぼかしによって失われた輪郭を先鋭化します。

一見すると、この手順はうまく動作しそうに思えます。

しかし、実際に試してみるとあまりうまくいきません。

理由ははっきりとは分かりませんが、
ガウシアンフィルターとアンシャープマスクフィルターは、
本質的には同じガウシアンぼかしを利用している処理であることが関係していると考えられます。


このため、別系統のフィルターを組み合わせる必要があります。

ただし、先鋭化処理については事情が少し異なります。
画像処理の分野では、輪郭を強調する方法として
アンシャープマスクフィルターがほぼ定番と言える存在です。

そのため、別のフィルターを組み合わせるとしても、
先鋭化処理自体はアンシャープマスクを使うことになる可能性が高いです。

とはいえ、本来であれば
先鋭化処理を行わなくても済む方法が理想的です。


まず、メディアンフィルターですが、
これはノイズ除去としては非常に強力な反面、
処理が強すぎて画像のディテールまで崩してしまいます。

次に、バイラテラルフィルターも試しました。
これはエッジを保ちながら平滑化するフィルターですが、
スクリーントーンのパターンをノイズとして認識してくれないことが多く、
期待したほどトーンが消えません。
場合によっては、画像全体がぼやけるだけになってしまいます。

また、モルフォロジー変換も検討しましたが、
こちらは基本的に2値画像を対象とした処理であり、
線画のような細いディテールでは1pxの線が簡単につぶれてしまいます。

このため、今回の用途には少し処理が粗すぎる印象でした。


いろいろ試してみた結果、
ノンローカルミーンフィルター(Non-Local Means Filter)が一番良い結果になりました。

もちろん万能というわけではなく、
パラメータ設定に大きく依存します。

パラメータが弱すぎるとトーンの格子模様が残り、
強すぎると今度は画像全体がぼやけてしまいます。

しかし、うまく調整すれば
トーン由来の細かいパターンだけを弱めつつ、線画のディテールを比較的よく保つことが出来ます。

完全にトーンを除去できるわけではありませんが、
従来型の画像フィルターの中では、比較的バランスの良い結果になりました。


ただし、トーンを完全に消すような強いパラメータに設定すると、
今度は画像のディテールまでつぶれてしまいます。

ここで、ある程度妥協するというのも一つの方法ではありますが、
機械学習AIの力を借りるという手もあります。

StableSRは、Real-ESRGANのような従来型の超解像とは少し性格が異なり、
生成AIに近い仕組みで画像を再構成する手法です。

そのため、単純に画像を拡大するというよりも、
画像を描き直すような処理になります。

この考え方で見ると、これまで行ってきた

  • 縮小
  • フィルタ処理
  • トーンの格子模様の低減

といった作業は、
最終的な画像を生成するための下絵を作る工程と考えることができます。

つまり、トーンを完全に消すことを目標にするのではなく、
AIが再構成しやすい状態まで画像を整えることが目的になります。

最終的にAIの力を借りるという点では、
ある意味で妥協とも言えるかもしれません。

しかし、せっかく便利な技術があるのですから、
それを使うことに特にためらいはありません

コメント