読者です 読者をやめる 読者になる 読者になる

kentsu tech Lab

何かその時の興味でいろいろする人。最近はScala使ってる。LinuxとアルゴリズムとOSSが大好き。

メディアンフィルタ

画像処理 Python

メディアンフィルタ

移動平均法ではn*nの局所領域における濃度の平均値を領域中央の画素が保有する濃度として扱ったが
別の画質改善法にメディアンフィルタというものがある
これは局所領域中の濃度値の中央値を領域中央の画素が保有する濃度として扱う方法である

例えば以下のような画素の一次元配列が存在すると仮定する
1,4,5,6,7,3,2,9,5
これを移動平均方では平均値を領域中央として扱ったが
メディアンフィルタでは
1,2,3,4,5,5,6,7,9
と並べ替えて中央値を領域中央の値とする

詳しい仕組み

メディアンフィルタでは、局所領域における画素の中央値を扱うため
その領域内の画素に対して非線形な演算を必要とするが、領域内の要素数を奇数にする
つまりnを奇数としてn*nの領域に対して処理を行うことで中央値を一意に求めることが可能になる

メディアンフィルタの使いところ

メディアンフィルタは雑音、つまりノイズが画像の内容と無関係でランダムな白色雑音の時に有効な手段としてつかえる
これはメディアンフィルタによる処理を行うことでスパイク状の雑音が取り除かれることとエッジがボケることが少ないためである

平均値を取る移動平均法のような手段では処理を重ねていくたびに周辺画素への影響が大きくなるが
メディアンフィルタのように中央値を選ぶことで極端な値の影響を非線形な演算が吸収しているためである

OpenCVPythonで実装してみる


いつもどおりPythonOpenCVメディアンフィルタをかけてみる

#coding:utf-8

import numpy as np
import cv2

#画像を読み込み
img = cv2.imread("lenna256.png")
#グレースケール化
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
#これは奇数にしておく必要がある
k = 3

res_img = cv2.medianBlur(gray,k)

cv2.imshow("median filter",res_img)
cv2.waitKey(0)
cv2.destroyAllWindows()


ここで使った画像はいつものlenna256.png
これをグレースケール化してlenna256_median.pngを生成する

lenna256.png
f:id:RabbitFoot141:20160403113730p:plain

そしてこれがメディアンフィルタを適用させた画像
lenna256_median.png
f:id:RabbitFoot141:20160403113807p:plain

他の画質改善手法に比べてスパイク雑音を取り除き、エッジに与える作用が小さいので
移動平均法などに比べて、連続した部分は滑らかになり
輪郭線もある程度はっきりしている