こんにちは、エンジニアのさもです
今回はぼやけた画像の輪郭をくっきりさせる、アンシャープマスキングを実装したいと思います。
スポンサーリンク
目次
はじめに
前回まで頻繁にぼかし処理を使ってきました。
例えば、こちらの新幹線の写真
この写真へぼかし処理を行うと、以下のようになります。
このぼやけた画像へアンシャープマスキングをかけてみると、以下のようになります。
ほんの少し輪郭がはっきりしたでしょうか。
それでは、実装をしていきます。
スポンサーリンク
実装
アンシャープマスキングは、画像の各画素を、その画素と周辺画素にフィルターをかけた値で置き換えます。
- フィルター
kはアンシャープマスキングの効果の強さで、大きいほど効果が大きくなります。
from PIL import Image, ImageDraw import numpy as np # アンシャープフィルタをかけた画像を返す def unsharp_filter(img, w, h, k): # STEP1 pixcels = np.array([[img.getpixel((x,y)) for x in range(w)] for y in range(h)]) filtered_img = Image.new('RGB', (w, h)) cr = 1 + 8 * k / 9 ar = - k / 9 # STEP2 for x in range(w): for y in range(h): if x == 0 or x == w - 1 or y == 0 or y == h - 1: # STEP2-1 filtered_pixcel = pixcels[y][x] else: # STEP2-2 filtered_pixcel = ar * pixcels[y - 1][x - 1] + ar * pixcels[y - 1][x] + ar * pixcels[y - 1][x + 1]\ + ar * pixcels[y][x - 1] + cr * pixcels[y][x] + ar * pixcels[y][x - 1]\ + ar * pixcels[y + 1][x - 1] + ar * pixcels[y + 1][x] + ar * pixcels[y + 1][x + 1] # STEP2-3 filtered_img.putpixel((x,y), (tuple(list(map(int, filtered_pixcel))))) return filtered_img # 画像ファイルの読み込み filename = "sin.jpg" img = Image.open("../images/" + filename).convert("RGB") w, h = img.size # 画像へアンシャープマスキングをかける unsharp_img = unsharp_filter(img, w, h, 1) unsharp_img.save("./unsharp_" + filename)
今回はコードが短いので一気に書きました。
- STEP1
- 変数の定義です
- cr, ar は上の説明で登場したとです
- STEP2
- STEP2-1
- 端っこの画素は正方形のフィルタがかけられないので、そのままの値を表示します
- STEP2-2
- 上のフィルタを適応しています
- STEP2-3
- フィルタをかけたあとの値は整数ではないので、整数に変換して画素を画像へ置いていきます
- STEP2-1
実行
上記コードをunsharp.pyという名前で保存します。
適当な画像を用意しておき、以下を実行します。
python unsharp.py
ぼやけた画像を作って試したいという方は、以下の記事中の「平滑化フィルタを事前に通しておく」を参考にしてみてください
よりシャープに
kとして10を選んだときの実行結果がこちらです。
くっきりしましたね。
最後に
今回でシリーズ?5回目になりました!
すこしpythonに慣れてきたかなという感じです。
これまでの画像処理では2重のfor文を使ってきましたが、これだと遅いので、高速化する方法の記事も書きたいと思います
読者登録いただければはげみになりますので、よろしくお願いします。