這是模式識別的一個實驗,參考文獻是:
[1] L. Zhao, L.S. Davis, “Iterative figure-ground discrimination,” 17th International Conference on Pattern Recognition (ICPR), vol. 1, pp. 67-70, 2004.
[2] Automatic Pedestrian Segmentation Combining Shape, Puzzle and Appearance,2013
原理:略
算法步驟:
令
初始化:
初始的前景概率圖爲一個先驗統計圖PM, 即
先驗統計圖PM爲300幅前景掩碼圖的疊加:
開始迭代,設置迭代次數:
S-步驟:
M-步驟:
計算前景和背景概率:
根據下式更新圖像中所有像素點屬於前景和背景的概率
x——採樣點
y——圖像中所有的點
歸一化:
結果圖:
代碼:
# -*- coding: utf-8 -*-
# Author: XieYi
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import math
from sklearn import preprocessing
from skimage import filters
import matplotlib.cm as cm
import time
"""
準備工作,讀入圖片
"""
img = Image.open("p26.bmp")
img = img.convert('L')
img = np.array(img,'f')
img = img/img.max()
m,n = img.shape
imgVector = img.reshape((m*n,1))
# 參數
c = 1.0
sigma = 0.005 # 控制邊界精度,即模糊程度sigma越大越模糊
sampleRate = 0.05
"""
讀入模板
"""
#將前三列置0
mask = Image.open('mask.png')
mask = mask.convert('L')
mask = mask.resize((n,m))
mask = np.array(mask,'f')
mask[:,:3] = 0
# 採樣點,初始化F0和B0
nSamples = int(sampleRate * m * n)
F0 = np.zeros((m*n,1))
F0 = mask.reshape((m*n,1))
F0max = F0.max()
F0 = F0 / F0max
B0 = 1-F0
F, B = F0, B0
#迭代
t0 = time.time()
for i in np.arange(6):
print str(i+1),"次迭代...."
#S步
samples = np.zeros((nSamples,1))
for j in np.arange(nSamples):
y = np.random.randint(0, m-1)
x = np.random.randint(0, n-1)
samples[j,0] = y * n + x
#M步
f = np.zeros((m*n,1))
b = np.zeros((m*n,1))
for Xi in np.arange(nSamples):
posSample = samples[Xi,0]
valueSample = imgVector[samples[Xi,0],0]
diffMat = imgVector - np.tile(valueSample,(m*n,1))
diffMat = diffMat**2
expDiff = np.exp(-diffMat / 2.0 / (sigma**2))
f = f + c * (F[posSample,0]) / math.sqrt(2*math.pi) / sigma * expDiff
f = f * F
min_max_scaler = preprocessing.MinMaxScaler()
f = min_max_scaler.fit_transform(f)
for Yi in np.arange(nSamples):
posSample = samples[Yi,0]
valueSample = imgVector[samples[Yi,0],0]
diffMat = imgVector - np.tile(valueSample,(m*n,1))
diffMat = diffMat**2
expDiff = np.exp(-diffMat / 2.0 / (sigma**2))
b = b + c * (B[posSample,0]) / math.sqrt(2*math.pi) / sigma * expDiff
b = b * B
b = min_max_scaler.fit_transform(b)
add = f + b
f = f / add
b = 1 - f
F, B = f, b
output = F.reshape((m,n))
plt.imsave(str(i+1), output, cmap=cm.gray)
plt.figure(str(i+1))
plt.imshow(output,cmap=cm.gray)
print "time:",time.time() - t0
thresh = filters.threshold_otsu(output)
dst =(output >= thresh)*1.0
plt.figure("output")
plt.imshow(dst,cmap=cm.gray)
# 直接利用閾值分割
threshImg = filters.threshold_otsu(img)
dstImg =(img >= threshImg)*1.0
plt.figure("Img")
plt.imshow(dstImg,cmap=cm.gray)
plt.show()