OpenCV で画像をぼかすには、平滑化関数の cv2.blur を使える。出力画像 = cv2.blur(入力画像,(平滑化フィルタ幅,平滑化フィルタ高さ)) でぼかした画像を取得できる。
コードについて
実用上、ぼかしには2種類のパラメータがあると考える。1つは、「周辺の情報をどれだけ広く取り込むか」で、もう1つは、「元画像にぼかし画像をどれくらいの比率で混ぜるか」だ。
元画像を渡すと、ぼかした画像を返す関数 b を下記コードとして定義した。関数 b は、2番めの引数で広さを、3番めの引数で元画像と混ぜる比率を、それぞれ指定できるようにした。
# ぼかす
def b(img1,i,v):
img2 = cv2.blur(img1,(i,i))
img1f = np.float32(img1)
img2f = np.float32(img2)
return ct(img1f * (1. - v) + img2f * v)
# 値を0-255にclipして、typeをuint8にする
def ct(img):
return np.clip(img,0,255).astype(np.uint8)
コード全文は下記。実行時に画像ファイル名を渡して動かす。
import cv2
import sys
import numpy as np
# ぼかす
def b(img1,i,v):
img2 = cv2.blur(img1,(i,i))
img1f = np.float32(img1)
img2f = np.float32(img2)
return ct(img1f * (1. - v) + img2f * v)
# 値を0-255にclipして、typeをuint8にする
def ct(img):
return np.clip(img,0,255).astype(np.uint8)
file_name = sys.argv[1]
img = cv2.imread(file_name)
img2 = b(img,30,0.3)
cv2.imwrite(file_name.replace(".",".out."),img2)
広さの調整
コードに画像を渡して実行してみる。まずは「周辺の情報をどれだけ広く取り込むか」のパラメータ i を動かす。
広さを広くする方が、強くぼけ、印象派の絵画に似てくる。柔らかみが増し、ノイズが減る。特に遠くから見ると綺麗に見えるが、近くから見るとただのピンぼけで、細かい部分が物足りない。
元画像との混合比率の調整
混合比率 v も動かしてみる。ぼかしの柔らかみと、細かい部分の情報の表示を同時に実現できるようになる。
この画像の場合、広さ i = 30 比率 v = 0.3 ( = 元画像が 0.7)が柔らかくも鮮明で良い感じだ。広くぼかして、それを元画像に少しだけ混ぜるのが良いらしい。
余談
余談だが、ぼかしの関数は混合比率 v をマイナスに設定することで、鮮明化の関数にもなる。
コメント
[…] OpenCV で濃淡をはっきりさせるために、「ぼかしを引く」という操作をする。元画像に「ぼかし」を混ぜると輪郭が曖昧になるが、逆に「ぼかし」を引くと輪郭を強調できる。コードはぼかしの記事とほぼ同じ。パラメータ v を負の値に設定して画像を編集する。 […]