【问题标题】:Using Markov Chain to transfom a RGB image to black and white(0-1)使用马尔可夫链将RGB图像转换为黑白(0-1)
【发布时间】:2021-05-23 08:57:03
【问题描述】:

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

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

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

这是我们开始的,经典。

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

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

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

【问题讨论】:

    标签: python image machine-learning image-processing markov-chains


    【解决方案1】:

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

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

    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()
    

    下一个动画展示了如何使用上述代码生成二进制图像。

    【讨论】:

    • 请问nbd 是什么?
    • 邻域,一般考虑 4 & 8 个邻域像素
    • 我正在尝试理解您的代码。您有 4 行 count += np.mean() > th。这是平均 4 个邻居的 RGB 值吗?如果是这样,这是相当浪费的,因为您在图像上进行了 2 次传递,并将大多数像素平均为上方的邻居、下方的邻居、左侧的邻居和右侧的邻居。当然,您可以只计算一次平均值并保存它,而不是 8 次?
    • 你是对的。这可以通过创建中间灰度图像来更有效地完成。然而,对于一个小图像来说,这并不重要(因为它会提供一个线性加速 w.r.t. 时间复杂度)它会增加空间复杂度,我不想创建一个中间图像。实现的目标是演示如何使用马尔可夫链将彩色图像直接转换为二进制图像。如果时间复杂度是一个问题,我们应该创建一个中间图像来删除多余的np.mean()s。最后,训练/测试图像可以不同(此处相同)。
    猜你喜欢
    • 2013-03-17
    • 2020-02-17
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-17
    相关资源
    最近更新 更多