今回は深層学習(AI)を使って画像のノイズ除去をしてみます。
pythonでコードを書けば簡単ですが、あえてImageJ(Fiji)のプラグインで行います。
環境はWindows10、GPUはGeForce GTX 1060を使用しました。
深層学習を用いたノイズ除去はノイズのあるデータとノイズのないデータ(教師データ)を1セットで用いて学習する方法が主流です。
Noise2Noise(N2N)という手法は2つの異なるノイズ画像を用いて学習する方法で、Noise2Void(N2V)とはノイズ除去したい画像1枚のみ(またはセット)で学習する手法です。性能は制限されるものの、これらは教師データを用意できないような分野で有効です。今回使用する手法はN2Vです。
詳細は以下の論文を読んでください。アブストしか読めないですが・・・
Alexander Krull, Tim-Oliver Buchholz, and Florian Jug. “Noise2void-learning denoising from single noisy images.” Proceedings of the IEEE/CVF conference on computer vision and pattern recognition. 2019.
以下のような結果になるそうです。N2Vのドキュメントの画像を拝借しました。顕微鏡の画像みたいです。

N2Vプラグインを使うにはFijiが必要ですので、ここからダウンロードしてインストールします。
N2Vを利用可能なImageJ(Fiji)プラグインはここから見つけることができます。他にもいろいろなプラグインがあります。なお、N2VはCSBDeepというプラグインの一部として提供されています。
インストール方法はここに書いてある通りです。

N2Vのプラグイン自体は非常に簡単に使えるのですが、準備に少し手間がかかります。
深層学習にはGPUを使うのが一般的で、CPUでも学習可能ですが膨大な時間がかかります。(GPUを使ったとしても数時間かかりますので、CPUだと何日?)
このプラグインではNVIDIA製のGPUが必要な点に注意です。
そのため以下のような準備が必要です。
・(visual studio)
・imagej-tensorflow
・CUDA
・cuDNN
・PATHを通す
これらを準備する手順はここで示されています。
なお、windowsの場合は以下の部分を参考にするといいです。

しかし、インストールには少し手間取りました。環境変数が変更できなかったり、一番最後の行のtensorflow_jni.dllを上の階層に移動させないといけなかったり、ここに書いてある問題と同じ症状が出たり(誰かが回答してくれているようにupdateにtensorflowを加えると解決しました)。とりあえず、エラーが出ている場合は、エラーをそのままコピペしてググる、GPTに聞くのが必要です。
とりあえず以下のようになっていればGPUが使える状態になっています。Tensor flowとCUDA、cuDNNにはversionの依存性があるので、すべて新しいものを選択すればいいというわけではないことに注意です。

使用方法はいたって簡単です。
Plugin→CSBDeep→N2V→N2V train + predict
trainが学習過程で、predictが推論過程です。それぞれ別々に行うことも可能ですが、この順番で行う必要があります。

学習のための設定です。
今回は初期設定からほとんど変えていませんが、精度を上げるにはここを最適化する必要があります。いろいろと変えてみてください。

学習中です。・・・あれ?あんまりLossが減ってない?

長いのでepoch=50でFinish Trainingしました。epochが50/300で30分かかったので300やるとなると6時間くらいかかるということでしょう。
上が最もLOSSが少なかった学習データ、下が最後の学習データです。最後の学習データを使っておけばいいと思います。

画像のノイズを付与したのが下の写真(左)で、そこからN2Vによってノイズを除去したのが右です。

単純にガウシアンフィルタで平滑化した下の写真と比べて画質が良いことが分かります。

学習が終わったらモデルを保存することができます。predictする際にそのモデルを読み込むことで前回の学習データが使用できます。


今回はN2VをImageJ(Fiji)のプラグインで行う方法を説明しました。N2Vはpythonでも公開されていますので、そちらの方が色々と自由度が高いと思います。
プログラムを書けない方は上記の方法でお手軽に試してみましょう。