马尔科夫随机场做图像分割
1.1 题目的主要研究内容
(1)组的主要任务描述
本小组主要对贝叶斯分类器在不同方向的应用领域以及具体实现进行了综述。通过查阅资料后,发现贝叶斯分类器可以在图像分割,垃圾邮件判别,以及天气预测和机器学习等方向都有着非常强大的作用。
(2)自己工作的主要描述
马尔科夫随机场做图像分割。通过观测一副图像,可以知道图像的特征图,使用马尔科夫的特性,选取图像中一个点的8邻域,对图像的像素点类别进行随机初始化,这里可以通过设置随机数的方法或者K均值算法进行初始化,其次通过已经计算出的先验概率、条件概率(假设条件概率符合正态分布)来求得该像素点的后验概率,通过后验概率即可对图像进行分割。
1.2 题目研究的工作基础或实验条件
(1)硬件环境
本实验的硬件环境主要为:处理器Intel i7 7700HQ,显卡英伟达1050TI,内存联想DDR4 2400 8G * 2。
(2)软件环境
本实验的软件环境主要为Windows操作系统,Pycharm工具。
1.3 设计思想
通过马尔科夫随机场对图像进行分割,其核心主要是通过贝叶斯分类器来根据已知的先验概率求得图像中像素点的后验概率。
1.4 流程图
图1.1 马尔科夫随机场做图像分割流程图
1.5 主要程序代码
import cv2#引入程序所需的必要包
import numpy as np
img = cv2.imread('1.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #将图⽚⼆值化,彩⾊图⽚该⽅法⽆法做分割
img = gray
img_double = np.array(img, dtype = np.float64)
cluster_num = 2
max_iter =200
label=np.random.randint(1, cluster_num + 1, size = img_double.shape)
iter=0
f_u = np.array([0,1,0,0,0,0,0,0,0]).reshape(3, 3)#重新设置图片大小
f_d = np.array([0,0,0,0,0,0,0,1,0]).reshape(3, 3)
f_l = np.array([0,0,0,1,0,0,0,0,0]).reshape(3, 3)
f_r = np.array([0,0,0,0,0,1,0,0,0]).reshape(3, 3)
f_ul = np.array([1,0,0,0,0,0,0,0,0]).reshape(3, 3)
f_ur = np.array([0,0,1,0,0,0,0,0,0]).reshape(3, 3)
f_dl = np.array([0,0,0,0,0,0,1,0,0]).reshape(3, 3)
f_dr = np.array([0,0,0,0,0,0,0,0,1]).reshape(3, 3)
while iter < max_iter:
iter = iter + 1
print(iter)
label_u = cv2.filter2D(np.array(label, dtype = np.uint8), -1 , f_u) #对图像进行滤波操作
label_d = cv2.filter2D(np.array(label, dtype = np.uint8), -1 , f_d)
label_l = cv2.filter2D(np.array(label, dtype = np.uint8), -1 , f_l)
label_r = cv2.filter2D(np.array(label, dtype = np.uint8), -1 , f_r)
label_ul = cv2.filter2D(np.array(label, dtype = np.uint8), -1 , f_ul)
label_ur = cv2.filter2D(np.array(label, dtype = np.uint8), -1 , f_ur)
label_dl = cv2.filter2D(np.array(label, dtype = np.uint8), -1 , f_dl)
label_dr = cv2.filter2D(np.array(label, dtype = np.uint8), -1 , f_dr)
m, n = label.shape
p_c = np.zeros((cluster_num, m , n))
for i in range(cluster_num):
label_i = (i+1) * np.ones((m, n))
u_T = 1 * np.logical_not(label_i - label_u) #返回非逻辑后的布尔值。
u_T = 1 * np.logical_not(label_i - label_u)
d_T = 1 * np.logical_not(label_i – lab
u_T = 1 * np.logical_not(label_i - label_u)
d_T = 1 * np.logical_not(label_i - label_d)
l_T = 1 * np.logical_not(label_i - label_l)
r_T = 1 * np.logical_not(label_i - label_r)
ul_T = 1 * np.logical_not(label_i - label_ul)
ur_T = 1 * np.logical_not(label_i - label_ur)
dl_T = 1 * np.logical_not(label_i - label_dl)
dr_T = 1 * np.logical_not(label_i - label_dr)
temp = u_T + d_T + l_T + r_T + ul_T + ur_T + dl_T + dr_T
p_c[i, :] = (1.0/8) * temp
p_c[p_c == 0] = 0.001
mu = np.zeros((1, cluster_num))#生成包含零的数组
sigma = np.zeros((1, cluster_num)) #生成包含零的数组
for i in range(cluster_num):#对像素点进行循环
index = np.where(label == (i+1))
data_c = img[index]
mu[0, i] = np.mean(data_c)
sigma[0, i] = np.var(data_c)
p_sc = np.zeros((cluster_num, m , n))
one_a = np.ones((m, n))
for j in range(cluster_num):
MU = mu[0, j]* one_a
p_sc[j, :] = (1.0/np.sqrt(2 * np.pi * sigma[0, j])) * np.exp(-1. * (( img - MU)**2) /(2 * sigma[0, j]))
X_out = np.log(p_c) + np.log(p_sc)
label_c = X_out.reshape(2, m * n)
label_c_t = label_c.T
label_m = np.argmax(label_c_t, axis = 1)
label_m = label_m + np.ones(label_m.shape) # 由于上⼀步返回的是index下标,与label其实就差1,因此加上⼀个ones矩阵即可
label= label_m.reshape(m, n)
label = label - np.ones(label.shape) # 为了出现0
lable_w = 255 * label #此处做法只能显⽰两类,⼀类⽤0表⽰另⼀类⽤255表⽰
cv2.imwrite('label.jpg', lable_w)
1.6 运行结果及分析
经过上述方法对图像进行分割后,可以明显的看到图像被分成黑白两个部分,实验结果基本符合预期,如果想要进行更加细粒度的划分,还可以通过进一步调整算法的参数值来达到理想的效果。
图1.2 图像分割前
图1.3 图像分割后