SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ITエンジニアのためのスパースモデリング入門

スパースモデリングの画像処理への応用~画像の再構成とノイズ除去

ITエンジニアのためのスパースモデリング入門

画像データへの応用

 画像データに対して辞書学習を適用するときには、画像をパッチと呼ばれる小領域に切り出して扱うことが多いです。下図のように、画像の赤で囲まれた長方形領域に注目し、このパッチは辞書を少数組み合わせると作り出すことができるはずだと思うわけです。このとき、辞書もパッチと同じサイズの画像と思ってもよく、一般的に辞書はエッジやテクスチャを表すと考えられています。

画像の辞書学習
画像の辞書学習

 学習をする際は、画像のいろんなところからパッチを切り出し、それらをベクトル化することで行列を作ります。それでは、実際にやってみましょう。K-SVDアルゴリズムでは標準化をしておいた方が再構成しやすくなるので忘れずに行っておきましょう。

from PIL import Image
from sklearn.preprocessing import StandardScaler
from spmimage.feature_extraction.image import extract_simple_patches_2d, reconstruct_from_simple_patches_2d

img = np.asarray(Image.open("img/recipe.jpg").convert('L'))

patch_size = (8, 8)
patches = extract_simple_patches_2d(img, patch_size)
patches = patches.reshape(-1, np.prod(patch_size)).astype(np.float64)
scl = StandardScaler()
Y = scl.fit_transform(patches)

 そして、得られた\(Y\)に対してK-SVDアルゴリズムを適用してみます。

ksvd = KSVD(n_components=50, transform_n_nonzero_coefs=5)
X = ksvd.fit_transform(Y)
D = ksvd.components_

 まずは、うまく学習ができたかどうかを再構成誤差を求めることで確かめてみましょう。パッチごとに再構成誤差を求める方法もありますが、ここでは、再構成されたパッチから再構成画像を構築し、元の画像と比較する方法で確かめてみます。

reconstructed_patches = np.dot(X, D)
reconstructed_patches = scl.inverse_transform(reconstructed_patches)
reconstructed_patches = reconstructed_patches.reshape(-1, patch_size[0], patch_size[1])
reconstructed_img = reconstruct_from_simple_patches_2d(reconstructed_patches, img.shape)
reconstructed_img[reconstructed_img < 0] = 0
reconstructed_img[reconstructed_img > 255] = 255
reconstructed_img = reconstructed_img.astype(np.uint8)
画像の再構成
画像の再構成

 左が元画像、右が再構成画像です。人が見ても大きな違いはないように見えます。PSNR、SSIMという画像の類似度を定量的に測る一般的な指標の計算もしてみましょう。

from skimage.metrics import peak_signal_noise_ratio as compare_psnr
from skimage.metrics import structural_similarity as compare_ssim

print("PSNR:", compare_psnr(img, reconstructed_img))
print("SSIM:", compare_ssim(img, reconstructed_img))
PSNR: 34.77376225983931
SSIM: 0.9279544257655109

 どちらの指標においても、両者の画像はかなり似ているということが言えます。次に、得られたスパースコードの行列と、辞書を二次元化したものを見てみましょう。

画像のスパースコードと辞書
画像のスパースコードと辞書

 辞書を見ると、エッジを表現するための成分や、質感を表すテクスチャの成分などが抽出されていることがわかります。そして、このスパースコードの行列を見ることによって、各パッチを表現するためにはどのように辞書を組み合わせればいいかを知ることができます。

画像のノイズ除去

 最後に画像の辞書学習再構成をうまく活用してノイズ除去に挑戦してみましょう。冒頭では、ランダムな行列はスパースに表現することはできないので、再構成がうまくできないという話をしました。一方で自然画像に対しては、パッチに区切ることでうまくスパースに表現することができました。では、綺麗な画像にランダムなノイズが付与されている場合、そのような画像に対して、辞書学習したらどうなるでしょうか。辞書学習によって、辞書とスパースコードには綺麗な画像に関する成分のみ抽出される、つまり、得られた辞書とスパースコードで再構成画像を作ると綺麗な画像を復元することができるのでしょうか。実際にやってみましょう。

 先ほどの画像に、各画素-10~10のランダムな値を加えてみます。

true_img = np.asarray(Image.open("img/recipe.jpg").convert('L'))
noise = (np.random.rand(*img.shape) - 0.5) * 20
img = true_img.copy().astype(np.float64) + noise

 このときの、元の画像とノイズ付加画像のPSNR、SSIMは次の通りです。

PSNR: 17.07698724442016
SSIM: 0.6886488280378513

 このノイズが付加された画像に対して、先ほどと全く同様の手順で辞書学習を適用し、再構成画像を計算してみましょう。

 元画像、ノイズ付加画像、再構成画像を左から順に下図に示します。

画像の辞書学習
画像の辞書学習

 そして、元画像と再構成画像のPSNRとSSIMは次の通りになりました。

PSNR: 34.034784549441824
SSIM: 0.8847876523679297

 ノイズ付加画像と比べると、PSNR、SSIMともに劇的に改善されていることがわかります。このように、単純に辞書学習を適用するだけで、画像のノイズ除去を行うことができます。逆にいうと、辞書学習によって、再構成画像を求めるということは画像の平滑化のようなフィルタをかけていると言うこともできます。

最後に

 さて、ここまで、辞書学習について、画像データへの応用を交えながら説明してきましたが、辞書学習のエッセンスを理解していただけたでしょうか。ここで用いたソースコードについては、GitHubで公開しています。

 詳細な理論やアルゴリズムについては説明を割愛しましたが、興味のある方は以下の文献を当たってみることをおすすめします。

 実は、ここで紹介した画像のノイズ除去は辞書学習の応用事例のうちの一つにすぎず、辞書学習は異常検知や超解像のような様々な応用事例があります。次回の投稿では、辞書学習の発展的な応用と実ビジネスでの活用などを紹介する予定ですので、お楽しみに。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
ITエンジニアのためのスパースモデリング入門連載記事一覧

もっと読む

この記事の著者

増井 隆治(株式会社HACARUS)(マスイ リュウジ)

 中学生の頃からプログラミングに興味を持ち、鈴鹿高専で情報学の基礎を学び、その後京都大学に編入し、より高度な数学を学ぶ。大学の実験で仲良くなった大関先生の紹介でハカルスでアルバイトを始める。3年間のアルバイトの後、2019年4月にハカルス初の新卒として入社。データサイエンティストの仕事に邁進している...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/11823 2019/11/26 11:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー