Pythonによる画像処理100本ノック#10 メディアンフィルタ


はじめに

どうも、らむです。
今回は画像中のノイズを除去するメディアンフィルタを実装します。

10本目:メディアンフィルタ

メディアンフィルタとは画像の平滑化・ノイズ除去を行うフィルタです。このフィルタを適用することによって画像全体をぼやかしたような加工ができます。

このフィルタでは注目画素を周辺画素の中央値で置き換えます。

また、前回同様、画像の端部分はフィルタリング処理が行えないので存在しない画素は0を用いる0パディング処理を行います。

ソースコード

medianFilter.py
import numpy as np
import cv2
import matplotlib.pyplot as plt


def medianFilter(img,k):
  w,h,c = img.shape
  size = k // 2

  # 0パディング処理
  _img = np.zeros((w+2*size,h+2*size,c), dtype=np.float)
  _img[size:size+w,size:size+h] = img.copy().astype(np.float)
  dst = _img.copy()

  # フィルタリング処理
  for x in range(w):
    for y in range(h):
      for z in range(c):
        dst[x+size,y+size,z] = np.median(_img[x:x+k,y:y+k,z])

  dst = dst[size:size+w,size:size+h].astype(np.uint8)

  return dst


# 画像読込
img = cv2.imread('image.jpg')

# メディアンフィルタ
# 第2引数:フィルタサイズ
img = medianFilter(img,15)

# 画像保存
cv2.imwrite('result.jpg', img)
# 画像表示
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.show()

  

画像左は入力画像、画像中央は前回のガウシアンフィルタによる出力画像、画像右は今回の出力画像です。
メディアンフィルタでは点状のノイズがきれいさっぱり除去できていることが分かります。
引数が違うのであまりいい比較にはなっていないですが、メディアンフィルタの方が点状のノイズをきれいに除去できています。

おわりに

もし、質問がある方がいらっしゃれば気軽にどうぞ。
imori_imoriさんのGithubに公式の解答が載っているので是非そちらも確認してみてください。
それから、pythonは初心者なので間違っているところがあっても優しく指摘してあげてください。