コンピュータサイエンス系勉強ノート

計算機科学に限らず日々学んだことを色々まとめていきます

マルコフ確率場を用いたノイズ除去を組んでみた(Python)

確率伝播法を使う必要がでてきたので,まずはマルコフ確率場についての勉強をしました.今回はマルコフ確率場上で画像上のノイズを除去するサンプルプログラムを組んでみました.

ソースコード

#encoding:utf-8
import numpy as np
import cv2
import matplotlib.pyplot as plt
from skimage.filters import threshold_otsu

def MRF(image):
    iter = 30
    height, width = image.shape
    dy = [-1,-1,-1,0,0,1,1,1]
    dx = [-1,0,1,-1,1,-1,0,1]
    reference = np.copy(image)
    alpha = 2.5
    beta = 4.0

    for t in range(iter):
        print(t)

        prob0 = np.zeros(reference.shape)
        prob1 = np.zeros(reference.shape)

        for i in range(1, height - 1):
            for j in range(1, width - 1):
                for k in range(len(dy)):
                    if reference[i+dy[k],j+dx[k]] == 1:
                        prob1[i,j] -= beta
                        prob0[i,j] += beta
                    else:
                        prob1[i,j] += beta
                        prob0[i,j] -= beta

        prob1[image == 1] -= alpha
        prob0[image == 0] -= alpha

        reference[prob1 > prob0] = 0
        reference[prob1 < prob0] = 1

    return reference


def get_corrupted_input(img, corruption_level):
    corrupted = np.copy(img)
    inv = np.random.binomial(n=1, p=corruption_level, size=img.shape)
    for r in range(img.shape[0]):
        for c in range(img.shape[1]):
            if inv[r, c]:
                corrupted[r, c] = ~(corrupted[r, c].astype(bool))
    return corrupted

def main():
    image = cv2.imread("Lenna.png", 0)
    binary = image > threshold_otsu(image)
    noise = get_corrupted_input(binary.astype(np.int), 0.05)
    denoise = MRF(noise)

    plt.gray()
    plt.subplot(131)
    plt.imshow(image)
    plt.subplot(132)
    plt.imshow(noise)
    plt.subplot(133)
    plt.imshow(denoise)
    plt.show()

if __name__ == '__main__':
    main()

実行結果

f:id:clientver2:20160622005909p:plain