画像のぼかし(ブラー)処理は、ノイズ除去や画像の前処理として広く活用されます。OpenCVには複数のぼかし手法が用意されており、用途に応じて使い分けることが重要です。
この記事では、フィルタ(カーネル)の基本概念から、OpenCVが提供する4種類のぼかし関数までを解説します。
事前準備
import cv2
import matplotlib.pyplot as plt
import numpy as np
image = cv2.imread('input/fox.jpg')
height, width = image.shape[:2]
image = cv2.resize(image, (round(width / 4), round(height / 4)))
フィルタ(カーネル)とは
画像処理におけるフィルタの正体は、奇数サイズの二次元正方行列(3×3、5×5など)です。これはカーネルとも呼ばれます。

このカーネルを画像の各ピクセルに対して畳み込み(convolution)演算することで、画像にさまざまな効果を与えます。
自作カーネルによる画像処理
自作カーネルでフィルタリングする場合はcv2.filter2D()を使用します。
cv2.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])引数
| 引数 | 説明 |
|---|---|
| ddepth | 出力画像の深度(データ型)。-1で入力画像と同じ型 |
| kernel | フィルタ(カーネル)。NumPy配列で指定 |
| anchor | カーネルのアンカーポイント。デフォルトは(-1, -1)(中心) |
| delta | フィルタリング結果に加算する値 |
| borderType | 画像の端の処理方法 |
Identity Kernel(恒等写像)
元の値と同じ値を返すカーネルです。変換前後で画像は変わりません。

# Identity Kernel作成
kernel1 = np.array([[0, 0, 0],
[0, 1, 0],
[0, 0, 0]])
# カーネル適用
identity = cv2.filter2D(src=image, ddepth=-1, kernel=kernel1)
Box blur(ぼかし)
すべての要素が同じ値のカーネルを使うと、画像をぼかすことができます。
# blur Kernel作成
kernel1 = np.ones((5, 5), np.float32) / 25
# カーネル適用
blur = cv2.filter2D(src=image, ddepth=-1, kernel=kernel1)
Sharpen(先鋭化)
画像の輪郭をくっきりさせる(シャープにする)カーネルです。
# Sharpen Kernel作成
kernel1 = np.array([[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]])
# カーネル適用
sharpen = cv2.filter2D(src=image, ddepth=-1, kernel=kernel1)
OpenCVの関数でフィルタリングする
OpenCVにはフィルタリング用の関数があらかじめ用意されています。一般的な用途では、自作カーネルよりもこれらの関数を使用するのが効率的です。
ぼかし(cv2.blur())
cv2.blur()は単純な平均化フィルタで、画像全体を均一にぼかします。
cv2.blur(src, ksize[, dst[, anchor[, borderType]]])| 引数 | 説明 |
|---|---|
| ksize | カーネルのサイズ |
| anchor | アンカーポイント。デフォルトは(-1, -1) |
| borderType | 画像の端の処理方法 |
blur = cv2.blur(src=image, ksize=(5, 5))
ガウシアンぼかし(cv2.GaussianBlur())
ガウシアンぼかしは加重平均を用いたフィルタリングです。カーネルの中心からの距離に基づいて重みづけされ、中心に近いほど影響が大きくなります。
cv2.blur()が均一なぼかしであるのに対し、cv2.GaussianBlur()は重みづけにより見た目が自然なぼかしが得られます。ただし、重みづけ計算を行う分、処理速度は低下します。
cv2.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]])| 引数 | 説明 |
|---|---|
| ksize | カーネルのサイズ |
| sigmaX | X軸方向のガウス関数の標準偏差 |
| sigmaY | Y軸方向のガウス関数の標準偏差 |
blur = cv2.GaussianBlur(src=image, ksize=(5, 5), sigmaX=0, sigmaY=0)
中央値ぼかし(cv2.medianBlur())
中央値ぼかしは、各ピクセルをカーネル領域内のピクセルの中央値に置き換える手法です。ごま塩ノイズと呼ばれるような画像のざらつきを除去する場合に効果的です。
cv2.medianBlur(src, ksize[, dst])| 引数 | 説明 |
|---|---|
| ksize | カーネルのサイズ(正の奇数) |
median = cv2.medianBlur(src=image, ksize=5)
Bilateralフィルタ(cv2.bilateralFilter())
通常のぼかしではエッジ(輪郭)部分もぼかされてしまいます。Bilateralフィルタを使えば、エッジを極力残しながら画像をぼかすことができます。
cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])| 引数 | 説明 |
|---|---|
| d | フィルタリングに使用するピクセル近傍の直径 |
| sigmaColor | 色空間におけるフィルタの標準偏差 |
| sigmaSpace | 座標空間におけるフィルタの標準偏差 |
sigmaの値が10未満ではぼかし効果が小さく、150以上にすると漫画風のテイストになります。
bilateral_filter = cv2.bilateralFilter(src=image, d=9, sigmaColor=75, sigmaSpace=75)
エッジを維持したままぼかしが適用されていることが確認できます。
まとめ
今回は、OpenCVで画像をぼかす方法を紹介しました。
cv2.blur(): 単純な平均化フィルタ。画像全体を均一にぼかすcv2.GaussianBlur(): 加重平均による自然なぼかし。中心ほど影響が大きいcv2.medianBlur(): 中央値によるぼかし。ごま塩ノイズの除去に有効cv2.bilateralFilter(): エッジを残しながらぼかす
処理が複雑なほど処理速度は低下するため、精度と速度のバランスを考慮して手法を選択してください。