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

kentsu.log

何かその時の興味でいろいろする人。最近はScala使ってる。アルゴリズムと自然言語処理、深層学習が大好き。

移動平均法

移動平均

今回は移動平均法を自分で実装してみた
そもそも移動平均法とは、一枚の画像に含まれるノイズを除去する基本的な手法の一つで
入力画像における(i,j)成分の濃度に対しその近傍の濃度値の平均値を出力画像の(i,j)成分とする方法のこと
その過程により画像の濃度のばらつきを低下させるため必然的にノイズも除去されるが
出力画像の輪郭などが鈍る傾向にある

具体的な処理

近傍の濃度値の平均は以下の式で求めることが出来る

f:id:RabbitFoot141:20160225005129p:plain

ここでの[]はガウス記号

実際この通りにコードを書いていけばいいが
プログラミングで扱う以上リストや配列の範囲を超える場合があるので
その時のループはスキップすることで実装できる

コード

#coding:utf-8

import numpy as np
import math
import cv2

#ガウス記号が示すものを関数化したもの
def gauss(number):

	if 0 <= number:
		return int(math.floor(number))
	else:
		return int(math.ceil(number))

image = "lenna256.png"
result = "lenna256_move.png"

#今回は256次正方行列を使うため
#256*256画素にリサイズしたlenna256.pngを使用
img = cv2.imread(image)

#グレースケールに変換
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)


#移動平均法を行う
for row in range(0,len(gray)):
	for line in range(0,len(gray[0])):
		#近傍濃度の和
		s = 0
		#3x3の正方形で計算する
		n = 3

		for i in range(-1*gauss(n/2.0),gauss(n/2)+1):
			for j in range(-1*gauss(n/2.0),gauss(n/2)+1):
				
				if len(gray) <= i + row or len(gray[0]) <= j + line:
					continue
				s += gray[i+row][j+line]

		gray[row][line] = s/n**2
		
			
#cv2.imwrite(result,gray)
cv2.imshow("move average",gray)
cv2.waitKey(0)
cv2.destroyAllWindow()

結果

今回も例に習って256*256のlenna256.png

f:id:RabbitFoot141:20160225004935p:plain

そしてこれが移動平均法を使ってノイズ除去をしたlenna256_move.png

f:id:RabbitFoot141:20160225005018p:plain