Markdownで表示

画像復元

画像復元は劣化した画像を受け取り、きれいな画像を返します。LibreYOLOではrestoreタスクとして提供され、ノイズ除去、ぼけ除去、超解像を1つの出力契約で扱います。1枚のRGB画像を入力し、1枚のRGB画像を出力します。

定義

restoreタスクは1枚の画像を別の画像へ変換します。ノイズ除去、ぼけ除去、超解像は、同じ契約を共有するため、ここではすべて同じタスクです。モデルはRGB画像を受け取り、RGB画像を返します。元に戻すため学習した劣化の種類はAPIではなくチェックポイントの属性です。

推論結果ではresult.restoredに値が格納されます。これは(H, W, 3)のuint8 RGB配列を保持するRestoredImageペイロードです。.arrayはNumPy配列として返し、.save(path)はディスクへ書き込みます。result.restore_scaleには出力キャンバスのアップスケール倍率が記録され、解像度を維持するチェックポイントでは1です。result.boxesは空のままなので、confioumax_detはシグネチャの互換性のため受け付けますが効果はありません。save=Trueは注釈付き写真ではなく復元済み画像を直接書き込みます。

モデル

restoreには、取り除く劣化の種類で分かれた3つのファミリーが対応します。

NAFNetはノイズ除去器であり、LibreYOLOで学習できる唯一の復元ファミリーです。そのアーキテクチャはUNetブロックの非線形活性化を要素ごとの乗算へ置き換えます。公開済みチェックポイントはSIDDの実画像ノイズで学習され、出力は入力解像度を維持します。

Real-ESRGANは実用的なアップスケーラーです。バイキュービックによる縮小だけでなく合成劣化に対して学習された3つのチェックポイントがあり、4倍、2倍、低レイテンシ向けの小さく高速な4倍生成器を提供します。

SwinIRはSwin Transformerバックボーンを使って4倍にアップスケールします。公式の軽量生成器と2つの実環境向け生成器を含む3サイズがあります。

推論

重みは初回使用時にHugging Faceからダウンロードされ、ローカルにキャッシュされます。

画像をアップスケール
from libreyolo import LibreYOLO, SAMPLE_IMAGE # 小型の4倍生成器 tileは大きなソースでピークメモリを制限するmodel = LibreYOLO("LibreRealESRGANx4t-restore.pt")result = model(SAMPLE_IMAGE, tile=512, tile_pad=10) result.restored.save("upscaled.png")print(result.restored.array.shape)   # 各軸で入力の4倍
画像のノイズを除去
from libreyolo import LibreYOLO, SAMPLE_IMAGE # SIDDの実画像ノイズで学習され出力は入力サイズを維持するmodel = LibreYOLO("LibreNAFNetl-restore-sidd.pt")result = model(SAMPLE_IMAGE) result.restored.save("denoised.png")print(result.restore_scale)   # 1 このチェックポイントではアップスケールなし

画像復元は固定されたネットワークキャンバスではなくソース画像本来の解像度で実行し、ネットワークのダウンサンプリング係数に合わせるためのパディングだけを行います。そのため、時間とメモリは入力のピクセル数に応じて増えます。tileは順伝播を重なり合うタイルへ分割し、境界を再び混合します。tile_padは各タイルへ追加し、後で切り取る周辺領域です。どちらもPythonのキーワード引数です。入力ソース、ストリーミング、結果の処理については推論を参照してください。

データセット形式

画像復元では、劣化した各入力画像を、まったく同じ解像度かつ同じファイル名の基幹部を持つきれいな対象画像と対応付けます。

dataset/
  data.yaml
  inputs/
    train/photo.jpg
    val/photo.jpg
  targets/
    train/photo.jpg
    val/photo.jpg
yaml
path: dataset
train: inputs/train
val: inputs/val
input_dir: inputs
target_dir: targets
degradation: denoise
dataset: MyDataset
nc: 1
names: {0: image}

ncnamesはスキーマ上のプレースホルダーです。復元モデルは検出ではなくResults.restoredを返します。degradationdatasetは任意の来歴ラベルです。target_stem_suffixは、きれいな画像に劣化画像とは異なる名前を使うデータセットに対応します。検証ではネイティブ解像度を維持し、バッチを積み重ねるために必要な分だけパディングするため、指標は元のキャンバス上で計算されます。完全な契約についてはデータセット形式を参照してください。

学習

学習実装を持つ復元ファミリーはNAFNetだけです。Real-ESRGAN.train()SwinIR.train()はどちらもNotImplementedErrorを送出します。これらのチェックポイントは合成劣化パイプラインを使うGAN学習から得られたもので、ペア画像の復元トレーナーではその手法を再現できないためです。

ペア画像でNAFNetをファインチューニング
from libreyolo import LibreYOLO model = LibreYOLO("LibreNAFNetl-restore-sidd.pt")model.train(data="my-dataset.yaml", epochs=100, imgsz=256, batch=16, lr0=1e-3)
チェックポイントに来歴を記録
from libreyolo import LibreYOLO model = LibreYOLO("LibreNAFNetl-restore-sidd.pt") # degradationとdatasetは来歴として保存済みチェックポイントへ# 書き込まれるが学習には関与しないmodel.train(    data="my-dataset.yaml",    epochs=100,    degradation="denoise",    dataset="MyDataset",)

トレーナーは入力と対象のペアを連動してクロップするため、両側の位置関係が維持されます。データセット、マルチGPU、ロガーについては学習、このファミリーのデフォルト値と学習時に切り離す推論用プーリングについてはNAFNetページを参照してください。

検証

val()は元のキャンバス上で、境界のクロップやサイズ変更を行わず、復元済み出力をきれいな対象とRGBで比較します。

検証して指標キーを確認
from libreyolo import LibreYOLO model = LibreYOLO("LibreNAFNetl-restore-sidd.pt") # val()はオブジェクトではなく通常のdictを返すmetrics = model.val(data="my-dataset.yaml") print(metrics["metrics/PSNR"])   # fitnessprint(metrics["metrics/SSIM"])

metrics/PSNRはデシベル単位のピーク信号対雑音比で、最良チェックポイントの選択で使うfitnessにもなります。metrics/SSIM[0, 1]範囲の構造的類似度で、シグマ1.5の11×11ガウシアン窓を使用し、3つのカラーチャンネルで平均します。どちらも大きいほど良い指標です。

エクスポート

エクスポートした復元モデルはファイルの拡張子に基づいてLibreYOLO()で再読み込みできるため、.onnx.engineファイルもチェックポイントと同様に動作します。返されるResultsではrestoredに出力画像が格納されます。

エクスポート
from libreyolo import LibreYOLO model = LibreYOLO("LibreNAFNetl-restore-sidd.pt") # imgszはグラフへ固定されるためデプロイ先で実際にモデルへ渡す# サイズを指定するmodel.export(format="onnx", imgsz=256)
エクスポートしたファイルを実行
from libreyolo import LibreYOLO, SAMPLE_IMAGE # ファクトリはファイルの拡張子に応じて振り分けるためエクスポートした# アーティファクトもチェックポイントと同様に読み込まれ同じResultsオブジェクトを返すmodel = LibreYOLO("LibreNAFNetl-restore-sidd.onnx")result = model(SAMPLE_IMAGE) result.restored.save("denoised.png")

復元モデルのエクスポートでは空間解像度をグラフへ固定するため、デプロイ先で実際にモデルへ渡すimgszを指定してください。NAFNetではそのサイズがネットワークのダウンサンプリング係数で割り切れる必要があり、dynamic=Trueでも動的になるのはバッチ次元だけです。Real-ESRGANとSwinIRでimgszを省略すると、実際の処理解像度ではなく小さな内部パッチサイズが使われます。形式ごとの対応範囲は各モデルページと完全なエクスポートマトリックスに記載されています。エクスポートには各形式で受け付ける引数が記載されています。

LibreYOLO v1.5.0で検証済みです。