天天看点

图像分割:马尔科夫随机场(Markov Random Field)--python实现直接上代码,原理大家都可以查到

直接上代码,原理大家都可以查到

注意:以下img自己加载即可,我是事先把图片转换成了单通道的Array形式,并且我的img是归一化后在0-1的。生成的label只有0,1两个值,迭代次数iter可以自己调整。

import cv2
import numpy as np

img_double = np.array(img, dtype=np.float64)
cluster_num = 2

max_iter = 200
img = img*255
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)
        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
           

继续阅读