这是模式识别的一个实验,参考文献是:
[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()