OpenCVには多数の画像フィルターがあります。また、numpyを使うと画像をピクセル単位で加工するフィルターを作成することが出来ます。個人的によく使う画像フィルター類をまとめたいと思います。
ライブラリのインポート
import cv2
import numpy as np
import os
osは画像加工には直接関係ないですが、画像ファイルの読み書きのパスの生成やファイルの有無の確認、ディレクトリの作成用
画像ファイルの読み込み
カラー読み込み
img = cv2.imread("F:/tmp/hoge.jpg",1)
グレースケールで読み込み
img = cv2.imread("F:/tmp/hoge.jpg",0)
パスに日本語?含むファイルは読み込めない。
画像ファイルの書き込み
cv2.imwrite("F:/tmp/hoge.jpg", img)
画像ファイルの書き込み
cv2.imwrite("F:/tmp/hoge.jpg", img)
画像の表示
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
CLI環境でウィンドウで画像を表示します。
任意のキーを押されるまで待ち、キーが押されるとウィンドウを破棄します。
2値化
result = np.where(gray < 128, np.uint8(0), np.uint8(255))
numpyのwhereを使って128をしきい値に0か255に分類する単純な方法
大須の2値化
ret,result = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)
適切なしきい値が自動的に設定されます。引数の閾値(0)は使われない模様。
グレースケール化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
imreadでカラーとして読み込んだ画像(BGR)をグレースケールへ変換
RGB[A] to Gray:Y←0.299⋅R+0.587⋅G+0.114⋅B
緑成分強め
ぼかし処理
result = cv2.blur(img, (3,3))
カーネルサイズは奇数
ガウシアンフィルター
result = cv2.GaussianBlur(img, (3,3), 0)
メディアンフィルター
result = cv2.medianBlur(gray, 3)
バイラテラルフィルター
result = cv2.bilateralFilter(gray, 3, sigmaColor=999, sigmaSpace=20)
ノンローカルミーンフィルター(グレースケール)
result = cv2.fastNlMeansDenoising(gray, h=15)
アンシャープマスキングフィルター
def unsharp(src, k=1.5):
kernel = np.array( [[-k/9.0, -k/9.0, -k/9.0],
[-k/9.0, 1.0+(8.0*k)/9.0, -k/9.0],
[-k/9.0, -k/9.0, -k/9.0]])
dst = cv2.filter2D(src, -1, kernel)
return dst
ガンマ補正
gamma = 0.9
x = np.arange(256)
y = (x / 255) ** gamma * 255
result = np.uint8(cv2.LUT(gray, y))
ソーベルフィルター
sobel_x = cv2.Sobel(gray, cv2.CV_32F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(gray, cv2.CV_32F, 0, 1, ksize=3)
sobel_x = cv2.convertScaleAbs(sobel_x)
sobel_y = cv2.convertScaleAbs(sobel_y)
result = cv2.addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0)
指定面積以下の物体を塗りつぶし
def fc(gray, am=9):
th=cv2.adaptiveThreshold(gray, 255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2)
contours,hierarchy = cv2.findContours(th, cv2.RETR_EXTERNAL | cv2.RETR_TREE , cv2.CHAIN_APPROX_NONE)
new_contours=[]
for c in contours:
s=abs(cv2.contourArea(c))
if s <= am:
new_contours.append(c)
cv2.drawContours(gray, new_contours, -1, 255, -1)
return gray
リサイズ
scale=4.0
result = cv2.resize(img, None, fx=scale, fy=scale, interpolation=cv2.INTER_LINEAR)
interpolation(補完方法)
cv2.INTER_NEAREST
cv2.INTER_LINEAR
cv2.INTER_AREA
cv2.INTER_CUBIC
cv2.INTER_LANCZOS4
画像の重ね合わせ
result = cv2.addWeighted(img1, 0.5, img2, 0.5, 0.0)
画像の減算
result = cv2.subtract(img1, img2)
ネガポジ反転
result = cv2.bitwise_not(img)
畳み込み演算による平滑化(ぼかし処理)
def avgBlur(src, ksize=3):
d = int((ksize-1)/2)
dst = src.copy()
(h, w) = src.shape[:2]
for y in range(d, h-d):
for x in range(d, w-d):
a = np.ravel(src[y-d:y+d+1, x-d:x+d+1])
dst[y][x] = np.mean(a)
return dst
OpenCVのfilter2Dメソッドと同じような動作をするフィルターをnumpyで記述しています。
サンプルでは平均をとるblurなのでnp.meanを使っていますが、カーネルを引数に取るようにすると、よりfilter2Dのような形になります。filter2dと比べて動作は遅いです。畳み込み演算の範囲外(外周部)はオリジナル画像のコピーをセットしています。
コメント