OpenCVでフィルタをいろいろ試してみるために作成しました。
import cv2
import numpy as np
import os
# HTMLのtitleとbodyを引数にヘッダと末尾を追加してHTMLを生成
def make_html_head(title="title", body=""):
return '''<!DOCTYPE html>
<html lang="en">
<head>
<title>{0}</title>
</head>
<body>
{1}
</body>
</head>'''.format(title, body)
# HTMLを保存
def save_html(path, html):
with open(path, mode="w") as f:
f.write(html)
# 画像を中心から指定サイズで切り出し
def trim_center(img, width, height):
h, w = img.shape[:2]
top = int((h / 2) - (height / 2))
bottom = top+height
left = int((w / 2) - (width / 2))
right = left+width
return img[top:bottom, left:right]
src_file = "D:/python/testdata/tmpC7D6.tmp_.png"
basename = os.path.splitext(os.path.basename(src_file))[0]
out_dir = "./filter_img"
if not(os.path.exists(out_dir)):
os.mkdir(out_dir)
img_table = []
body = ""
# 画像ファイルを読み込み
src = cv2.imread(src_file, 0)
# オリジナル
img_table.append( {
'title' : "Original",
'suffix' : "_org",
'image' : src
})
# ガウシアンフィルタ(5x5)
gblur = cv2.GaussianBlur(src, (5,5), -1)
img_table.append( {
'title': "Gaussian(5x5)",
'suffix': "_gblur",
'image': gblur
})
# アンシャープマスキングフィルタ
k = 2.5
kernel = np.array([[-k/9.0, -k/9.0, -k/9.0],
[-k/9.0, 1 + (8 * k)/9.0, -k/9.0],
[-k/9.0, -k/9.0, -k/9.0]])
sharp = cv2.filter2D(gblur, -1, kernel)
img_table.append( {
'title': "Gaussian->Sharp",
'suffix': "_sharp",
'image': sharp
})
# ノンローカルミーンフィルタ(h=15)
s_nlm = cv2.fastNlMeansDenoising(sharp, h=15)
img_table.append( {
'title': "Sharp->NonLocalMean",
'suffix': "_s_nlm",
'image': s_nlm
})
# ぼかし処理(3x3)
blur = cv2.blur(src, (3,3))
img_table.append( {
'title': "Blur(3x3)",
'suffix': "_blur",
'image': blur
})
# バイラテラルフィルタ
bil = cv2.bilateralFilter(src, 7, 150, 150)
img_table.append( {
'title': "BilateralFilter(7,150,150)",
'suffix': "_bil",
'image': bil
})
# ノンローカルミーンフィルタ(h=15)
nlm = cv2.fastNlMeansDenoising(src, h=15)
img_table.append( {
'title': "NonLocalMean(h=15)",
'suffix': "_nlm",
'image': nlm
})
# 2値化(バイナリ)
ret, th = cv2.threshold(src, 128, 255, cv2.THRESH_BINARY)
img_table.append( {
'title': "Threshold(Binary)",
'suffix': "_th",
'image': th
})
# 2値化(大須)
ret, th_otsu = cv2.threshold(src, 128, 255, cv2.THRESH_OTSU)
img_table.append( {
'title': "Threshold(OTSU)",
'suffix': "_th_otsu",
'image': th_otsu
})
# メディアンフィルタ
median = cv2.medianBlur(src, 3)
img_table.append( {
'title': "MedianBlur(3)",
'suffix': "_median",
'image': median
})
# ガンマ補正
g = 2.5
x = np.arange(256)
y = (x / 255) ** g * 255
gamma = cv2.LUT(src, y)
median = cv2.medianBlur(src, 5)
img_table.append( {
'title': "Gamma(2.5)",
'suffix': "_gamma",
'image': gamma
})
# ソーベル
sobel_x = cv2.Sobel(blur, cv2.CV_32F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(blur, cv2.CV_32F, 0, 1, ksize=3)
sobel_x = cv2.convertScaleAbs(sobel_x)
sobel_y = cv2.convertScaleAbs(sobel_y)
sobel = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0)
img_table.append( {
'title': "Sobel",
'suffix': "_sobel",
'image': sobel
})
# Canny
canny = cv2.Canny(blur, 0, 200)
img_table.append( {
'title': "Canny",
'suffix': "_canny",
'image': canny
})
# HTML出力ループ
i = 0
for row in img_table:
im = trim_center(row['image'], 128, 128)
im = cv2.resize(im, None, fx = 2.0, fy = 2.0, interpolation=cv2.INTER_NEAREST)
out_file = out_dir + "/" + "{0}{1}.png".format(basename, row['suffix'])
cv2.imwrite(out_file, im)
body += "<td><img src='{0}' /><br>{1}</td>\n".format(out_file, row['title'])
i += 1
if (i % 4) == 0:
body += "<tr></tr>"
path = ".\output.html"
html = make_html_head(title="ImageFilter Samples", body="<table><tr>" + body +"</tr></table>")
save_html(path, html)
コメント