この数日行っていたのがマウスクリックで画面上に領域を指定し、その部分をピンポイントで修正するプログラム製作です。画像の一部を処理する作業は「ROI(Region Of Interest)」と呼ばれているそうで、参考になるプログラムがオンラインで見つかりました。
【OpenCV】画像の一部のみ処理するROIの設定について【Python版】
このプログラムでは座標は予めコード内に記述しておく設定になっています。マウスクリックで座標を取得するプログラムは別に探しました。
OpenCVを使ってマウスイベント(手動)でテニスコート領域を選択できるようにする
クリックを4回するとその4点のxy座標をリストに格納し、その4点を頂点とする矩形を描くことができます。
「ROI」は矩形(台形などを含む)ではなく長方形しか処理できないようでしたので、4点クリックではなく左上と右下の2点クリックで座標を取得する形に修正します。ざっと書いたのが「denoising-roi2.py」(左)です。
先日スキャンした『聖女ベアトリクス伝説』からの一コマ。額の辺りに楕円形の汚れが付着しています。この部分をピンポイントで修復していきます。
プログラムを起動します。額の汚れの部分を左上と右下で挟みこむように2回クリック。すると自動でマスク画像が生成され、inpaint関数がそのマスク画像を介して元画像を修復していきます。
もう少し詳しい流れとしては:
1)加工用に元画像全体を一旦複製する(「dst_img」)
2)クリックした2点を対角線上の頂点とした長方形の画像「s_roi」を「dst_img」から抽出する
3)「s_roi」をhsv変換してからマスク画像「hsv_mask」を生成する
4)「hsv_mask」をパッチとし、inpaint関数で「s_roi」に修復をかけ画像「dst」を生成する
5)「dst」を「dst_img」の元の位置に置き換える
6)修復完了した画像を別名義で保存する(必要なら元画像を上書きする)
おでこの汚れを一か所消すだけにしては複雑な作業をしています。
参考サイトでは「ぼかし処理(blur関数)」を使っていて、これだと一行で済みます。ただぼかし処理は修復ではないんですよね。blur関数では下の結果になります。
散らした感じとなり四角い跡が残ってしまいます。
一方のinpaint関数は設定次第でかなり綺麗な修復結果になります。設定値「uppervalue(uv)」を変えながら修正結果の違いを比較してみます。

ほとんど変化なし

輪郭部分が残ってシミの様に見えます

だいぶ薄くなりました

かなり綺麗に消えています

uppervalueを150まであげるとダメージはほとんど見えなくなります。拡大するとうっすら輪郭は残っていますが、blur関数の様な不自然な感覚はありません。
フィルムのスキャン画像でダメージが一か所しかない、というのはあり得ない話で、傷や汚れは数ヶ所〜数十か所に及びます。そのまま修復システムに組みこむ感じではなさそう。それでもマウスクリック2回でxy座標を格納し、画像領域を指定してピンポイント修復出来るようになったのは収穫でした。