• 用OpenCV进行图像分割--进阶篇


    1. 引言

    大家好,我的图像处理爱好者们! 在上一篇幅中,我们简单介绍了图像分割领域中的基础知识,包含基于固定阈值的分割和基于OSTU的分割算法。这一次,我们将通过介绍基于色度的分割来进一步巩固大家的基础知识。

    闲话少说,我们直接开始吧!

    2. RG-色度空间

    基于色度的分割是指对每个像素的RGB值进行归一化处理,使我们的分割与光照条件无关。在开始之前,首先让我们讨论一下RG色度空间。它是一种二维的颜色表示,可以从我们的颜色中去除强度值,与标准的RGB空间的转化关系如下:
    在这里插入图片描述

    有的同学要问了,这里没有b, 实质上上述公式中, r 代表R在RGB中的占比,g代表G在RGB中的占比,剩下的 b 则是 1−r−g。
    可视化出的结果图如下:
    在这里插入图片描述

    一般来说,我们可以RG色度空间应用到我们基础的图像分割任务中,我们接下来通过示例进行相关说明。

    3. 导入样例图像

    按照惯例,我们首先来导入本样例所需示例图像,代码如下:

    # Import the necessary libraries
    from skimage.io import imread, imshow
    import matplotlib.colors as colors
    from skimage.color import rgb2gray
    import matplotlib.pyplot as plt
    import numpy as np
    # Display the original image
    original_image = imread('plants.jpg')
    plt.figure(figsize=(20,20))
    plt.imshow(original_image)
    plt.title('Original Image', fontsize=20, weight='bold')
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    得到结果如下:
    在这里插入图片描述

    4. 转到RG色度空间

    接着我们可以使用以下代码,实现原图到RG色度空间,代码如下:

    original_image_R = original_image[:,:,0]*1.0/original_image.sum(axis=2)
    original_image_G = original_image[:,:,1]*1.0/original_image.sum(axis=2)
    
    plt.figure(figsize=(20,20))
    plt.scatter(original_image_R.flatten(),original_image_G.flatten())
    plt.xlim(0,1)
    plt.ylim(0,1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    结果如下:
    在这里插入图片描述

    5. 选择模板图像

    这里我们选择一块绿色植物,作为我们的模板图像,代码如下:

    patch = original_image[3200:3300,2800:2900,:]
    plt.figure(figsize=(10,10))
    plt.imshow(patch)
    plt.title('Reference Patch for Green', fontsize=20, weight='bold')
    plt.axis('off');
    
    • 1
    • 2
    • 3
    • 4
    • 5

    结果如下:
    在这里插入图片描述

    接着,我们可以得到此模板图像的RG色度:

    patch_R = patch[:,:,0]*1.0/patch.sum(axis=2)
    patch_G = patch[:,:,1]*1.0/patch.sum(axis=2)
    
    plt.figure(figsize=(10,10))
    plt.scatter(patch_R.flatten(),patch_G.flatten())
    plt.xlim(0,1)
    plt.ylim(0,1);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    结果如下:
    在这里插入图片描述

    6. 计算高斯分布

    接着我们需要做的事就是计算我们模板图像的高斯分布,来找到我们感兴趣的颜色。因此,我们用以下代码计算模板图像R通道的平均值和方差,如下:

    std_patch_R = np.std(patch_R.flatten())
    mean_patch_R = np.mean(patch_R.flatten())
    
    • 1
    • 2

    我们来可视化下R通道计算出来的结果,代码如下:

    def gaussian(p,mean,std):
        return np.exp(-(p-mean)**2/(2*std**2))*(1/(std*((2*np.pi)**0.5)))
    x = np.linspace(0,1)
    y = gaussian(x,mean_patch_R,std_patch_R)
    plt.plot(x,y);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    画图如下:
    在这里插入图片描述

    这种分布为我们提供了使用R通道选择某种颜色作为图像表示的概率。我们实际上可以通过使用以下方法来利用该信息来分割我们的图像:

    prob_R = gaussian(original_image_R,mean_patch_R,std_patch_R)
    plt.imshow(prob_R);
    
    • 1
    • 2

    结果如下:
    在这里插入图片描述

    7. 分割图像

    上面只是使用了RG-色度空间的R通道进行分割的结果,同时我们类比计算G通道的分割结果,
    代码如下:

    std_patch_G = np.std(patch_G.flatten())
    mean_patch_G = np.mean(patch_G.flatten())
    prob_G = gaussian(original_image_G,mean_patch_G,std_patch_G)
    plt.imshow(prob_G);
    
    • 1
    • 2
    • 3
    • 4

    结果如下:
    在这里插入图片描述

    最后,我们考虑的两个通道是独立概率,我们可以简单地将掩码相乘:

    prob=prob_R * prob_G
    plt.imshow(prob)
    
    • 1
    • 2

    达到最终结果如下:
    在这里插入图片描述

    8. 总结

    通过上述分析,我们一步一步实现了利用RG-色度空间来分割绿色植物的目标,并针对每一步骤都进行了相应的讲解和代码示例,您学废了嘛!

  • 相关阅读:
    Hadoop伪分布式环境搭建
    刷题记录:牛客NC20276[SCOI2010]传送带
    微机原理练习题_13
    python 模拟后台点击
    力扣(LeetCode)1684. 统计一致字符串的数目(C++)
    如何靠写代码赚钱?
    Python绘图系统14:用tkinter做一个绘图风格控件
    Linux操作-1之内容切割命令cut
    智能计算之蚁群算法(ACO)介绍
    Wireshark 4.0.0 新版本发布
  • 原文地址:https://blog.csdn.net/sgzqc/article/details/131627249