使用马尔可夫链将 RGB 图像转换为黑白图像(0-1)

Using Markov Chain to transfom a RGB image to black and white(0-1)

我正在努力寻找这个问题的答案,我不太了解马尔可夫链的使用,我需要一些帮助:

[输入图像]https://i.stack.imgur.com/r9XCE.png

[输出图像示例]https://i.stack.imgur.com/3pllU.png

这就是我们的开头,经典。

我只想将此图像转换为黑白图像,但我必须使用我完全不理解的马尔可夫链概率

有人能给我一些提示吗? 我相信我们必须选择 N 次随机像素并应用 some proba 魔法将其更改为黑色或白色(基于概率和邻居)

提前致谢(我不是在搜索代码,而是在搜索要实现的逻辑)

这是一种使用马尔可夫链对图像进行二值化的方法:

假设(马尔可夫属性)一个像素值只依赖于它的邻居(假设一个 4-nbd),让我们估计一个像素是白色的概率,因为它的 nbd 像素是白色,即对于 4-nbd,让我们首先计算条件概率 P(x(i,j)=1 | n 的 nbrs 也为 1),其中 n=0,1,2,3,4 为 4 -nbd(另外,让我们使用全局阈值来计算概率,如以下代码所示,这可以被认为是训练阶段):

from skimage.io import imread
im = imread('https://i.stack.imgur.com/r9XCE.png')

def count_nbrs(im, i, j, th): # counts number of nbd pixels are 1 given a pixel, with threshold th
    count = 0
    count += np.mean(im[i-1,j]) > th
    count += np.mean(im[i+1,j]) > th
    count += np.mean(im[i,j-1]) > th
    count += np.mean(im[i,j+1]) > th
    return count

th = 140 #np.mean(im) # a global threshold
nnbrs = 5 # use 4-nbd
freq = np.zeros(nnbrs)
tot = np.zeros(nnbrs)
h, w, _ = im.shape
for i in range(1, h-1):
   for j in range(1, w-1):
      count = count_nbrs(im, i, j, th)
      if np.mean(im[i,j]) > th:
         freq[count] += 1
      tot[count] += 1
prob = freq/tot 
print(prob)
# Prob(x(i,j)=1|n of its nbrs are 1) in the image, for n=0,1,2,3,4
# [0.00775595 0.09712838 0.48986784 0.91385768 0.99566323]

现在让我们使用这些估计的概率将彩色图像中的每个像素更改为黑色和白色,具体取决于它的 nbd(这可以被认为是测试阶段):

h, w, _ = im.shape
im1 = np.zeros((h, w))
for i in range(1, h-1):
    for j in range(1, w-1):
        c = count_nbrs(im, i, j, th) # count number of neighbors with white pixel
        im1[i,j] = 255*(prob[c] > 0.5) # use Prob vector to determine value of the pixel
plt.imshow(im1, 'gray')
plt.show()

得到的二值图像质量远好于全局阈值处理(查看)。

您可以随机选择像素并计算给定1个nbrs(阈值)的像素值为1的概率,相应地设置像素值,使用以下具有大量迭代次数N的代码,它将产生相似的二值图像。

N = 100000
h, w, _ = im.shape
im1 = np.zeros((h, w))
for k in range(N):
    i = np.random.randint(1,h-1,1)[0]
    j = np.random.randint(1,w-1,1)[0]
    c = count_nbrs(im, i, j, th)
    im1[i,j] = 255*(prob[c] > 0.5) 
plt.imshow(im1, 'gray')
plt.show()

下一个动画展示了如何使用上面的代码生成二值图像。