• skimage学习(2)——RGB转灰度、RGB 转 HSV、直方图匹配


    1、RGB转灰度

    此示例将具有 RGB 通道的图像转换为具有单个灰度通道的图像。

    每个灰度像素的值计算为相应的红色、绿色和蓝色像素的加权和:

    Y = 0.2125 R + 0.7154 G + 0.0721 B
    
    • 1

    CRT 荧光粉使用这些权重,因为它们比同等权重更能代表人类对红色、绿色和蓝色的感知。

    import matplotlib.pyplot as plt
    
    from skimage import data
    from skimage.color import rgb2gray
    
    original = data.astronaut()
    grayscale = rgb2gray(original)
    #fig是一个变量名,fig代表绘图窗口(Figure);ax代表这个绘图窗口上的坐标系(axis),一般会继续对ax进行操作
    #其中figsize用来设置图形的大小,a为图形的宽, b为图形的高,单位为英寸。
    fig, axes = plt.subplots(1, 2, figsize=(8, 4))
    ax = axes.ravel()
    
    ax[0].imshow(original)
    ax[0].set_title("Original")
    ax[1].imshow(grayscale, cmap=plt.cm.gray)
    ax[1].set_title("Grayscale")
    
    fig.tight_layout()#ight_layout会自动调整子图参数,使之填充整个图像区域。这是个实验特性,可能在一些情况下不工作。它仅仅检查坐标轴标签、刻度标签以及标题的部分。
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    2、RGB 转 HSV

    hsv详解:https://blog.csdn.net/bamboocan/article/details/70627137
    这个例子说明了如何RGB到HSV(色调,饱和度,亮度)转换可以用来促进分割过程。
    通常,图像中的物体有不同的颜色(色调)和亮度,所以这些特征可以用来分隔图像的不同区域。
    在RGB表示中,色相和亮度表示为R、G、B通道的线性组合,而它们对应于HSV图像的单个通道(色相和值通道)。
    一个简单的分割图像,然后可以有效地执行仅仅阈值的HSV通道。

    比如图片染色均一化问题,我们常常用到rgb2hsv的手段来解决,可以有效的保护好纹理、分布等特征。
    这里我们看下染色体的颜色分离的一个例子:
    注意,这里的例子是HED颜色空间,HSV空间是同样的效果。

    from skimage import io
    import matplotlib.pyplot as plt
    
    import matplotlib.pyplot as plt
    
    from skimage import data
    from skimage.color import rgb2hsv
    #首先加载RGB图像并提取Hue和Value通道:
    rgb_img = data.coffee()
    hsv_img = rgb2hsv(rgb_img)
    io.imshow(hsv_img)
    plt.show()
    hue_img = hsv_img[:, :, 0]#它是对多维数据的一种处理方式,代表了前两维全选,取其中的所有0号索引。
    value_img = hsv_img[:, :, 2]
    value1_img = hsv_img[:, :, 1]
    
    fig, (ax0, ax1, ax2,ax3) = plt.subplots(ncols=4, figsize=(8, 2))
    
    ax0.imshow(rgb_img)
    ax0.set_title("RGB image")
    ax0.axis('off')
    ax1.imshow(hue_img, cmap='hsv')
    ax1.set_title("Hue channel")
    ax1.axis('off')
    ax2.imshow(value_img)
    ax2.set_title("Value channel")
    ax2.axis('off')
    ax3.imshow(value1_img)
    ax3.set_title("Value1 channel")
    ax3.axis('off')
    
    fig.tight_layout()
    #在Hue通道上设置一个阈值,将杯子从背景中分离出来:
    hue_threshold = 0.04#为什么这个通道是0.04
    binary_img = hue_img > hue_threshold
    
    fig, (ax0, ax1) = plt.subplots(ncols=2, figsize=(8, 3))
    
    '''
    plt.hist 函数用于绘制直方图。函数原型:
    plt.hist(x, bins=None)
    参数 x 是一个一维数组,bins 可以理解为矩形的个数,默认是 10。 
    '''
    ax0.hist(hue_img.ravel(), 512)#512 为直方图条形的个数 自己设定
    ax0.set_title("Histogram of the Hue channel with threshold")#Hue通道带阈值的直方图
    #matplotlib库的axiss模块中的Axes.axvline()函数用于在轴上添加一条垂直线。
    ax0.axvline(x=hue_threshold, color='r', linestyle='dashed', linewidth=2)
    #matplotlib库的axiss模块中的Axes.set_xbound()函数用于设置x轴的上下数值边界。
    ax0.set_xbound(0, 0.12)
    ax1.imshow(binary_img)
    ax1.set_title("Hue-thresholded image")
    ax1.axis('off')
    
    fig.tight_layout()
    #在Value通道上执行一个额外的阈值,以部分去除杯子的阴影:
    fig, ax0 = plt.subplots(figsize=(4, 3))
    
    value_threshold = 0.10
    binary_img = (hue_img > hue_threshold) | (value_img < value_threshold)
    
    ax0.imshow(binary_img)
    ax0.set_title("Hue and value thresholded image")
    ax0.axis('off')
    
    fig.tight_layout()
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    3、直方图匹配

    这个例子展示了直方图匹配的特性。它操作输入图像的像素,使其直方图与参考图像的直方图匹配。
    如果图像有多个通道,只要输入图像和参考图像中的通道数量相等,则对每个通道独立进行匹配。
    直方图匹配可以用作图像处理的轻量级归一化,例如特征匹配,特别是在图像从不同来源或不同条件(即光照)拍摄的情况下。

    import matplotlib.pyplot as plt
    
    from skimage import data
    from skimage import exposure
    from skimage.exposure import match_histograms
    
    reference = data.coffee()
    image = data.chelsea()
    
    matched = match_histograms(image, reference, channel_axis=-1)
    '''
    
    '''
    fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, figsize=(8, 3),
                                        sharex=True, sharey=True)
    for aa in (ax1, ax2, ax3):
        aa.set_axis_off()
    
    ax1.imshow(image)
    ax1.set_title('Source')
    ax2.imshow(reference)
    ax2.set_title('Reference')
    ax3.imshow(matched)
    ax3.set_title('Matched')
    
    plt.tight_layout()
    plt.show()
    #为了说明直方图匹配的效果,我们绘制每个RGB通道的直方图和累积直方图。
    # 很明显,每个通道的匹配图像与参考图像具有相同的累积直方图。
    fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(8, 8))
    
    #enumerate使得多了一个索引,同时还能读取到元素
    for i, img in enumerate((image, reference, matched)):
        for c, c_color in enumerate(('red', 'green', 'blue')):
            img_hist, bins = exposure.histogram(img[..., c], source_range='dtype')
            #各组数据除以数据中的最大值就是归一化处理。处理后最大值为1,其余的值均为小于 1 的数。
            #直方图中bin的含义:计算颜色直方图需要将颜色空间划分为若干小的颜色区间,即直方图的bin,通过计算颜色在每个小区间内德像素得到颜色直方图,bin越多,直方图对颜色的分辨率越强,但增加了计算机的负担。即(上图所分10个竖条区域,每个竖条区域称为一个bin)
            axes[c, i].plot(bin, img_hist / img_hist.max())
    
            img_cdf, bins = exposure.cumulative_distribution(img[..., c])
            axes[c, i].plot(bins, img_cdf)
            axes[c, 0].set_ylabel(c_color)
            print(c,i)
    axes[0, 0].set_title('Source')
    axes[0, 1].set_title('Reference')
    axes[0, 2].set_title('Matched')
    
    plt.tight_layout()
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    注解:
    1、返回图像的直方图

    cucim.skimage.exposure.histogram(image, nbins=256, source_range='image', normalize=False)
    
    • 1

    返回图像的直方图,与 numpy.histogram 不同,此函数返回 bin 的中心,并且不会重新组合整数数组。
    对于整数数组,每个整数值都有自己的 bin,这提高了速度和intensity-resolution。
    在展平图像上计算直方图:对于彩色图像,应在每个通道上单独使用该函数以获得每个颜色通道的直方图。
    参数:
    image:数组,输入图像。
    nbins:整数,可选,用于计算直方图的 bin 数量。对于整数数组,此值将被忽略。
    source_range:字符串,可选,‘image’(默认)确定输入图像的范围。 ‘dtype’ 确定该数据类型图像的预期范围。
    normalize:布尔型,可选,如果为 True,则通过其值的总和对直方图进行归一化。
    返回值:
    hist:数组,直方图的值。
    bin_centers:数组,bin中心的值。

    2、返回给定图像的累积分布函数 (cdf)。

    cucim.skimage.exposure.cumulative_distribution(image, nbins=256)
    
    • 1

    参数:
    image:数组,图像阵列。
    nbins:整数,可选,图像直方图的 bin 数量。
    返回:
    img_cdf:数组,累积分布函数的值。
    bin_centers:数组,箱子的中心。

    3、直方图匹配(histogram matching)
    含义:使源图像的累积直方图和目标图像一致
    from skimage.exposure import match_histograms
    参数1:源图像;参数2:目标图像;参数3:多通道匹配

    matched = match_histograms(image, reference, multichannel=True)
    
    • 1

    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    【无标题】【Koltin Flow(三)】Flow操作符之中间操作符(二)
    VUE3 之 列表动画 - 这个系列的教程通俗易懂,适合新手
    音视频播放器—快进快退及逐帧播放
    二、.Net Core搭建Ocelot
    Effective C++条款18:让接口容易被正确使用,不容易被误用
    用Python代码自己写Python代码,竟如此简单
    盘点国内主流数字孪生厂商!你了解几家?
    驱动编写LED灯
    MATLAB R2023a完美激活版(附激活补丁)
    VS2019中使用printf函数报错处理方法
  • 原文地址:https://blog.csdn.net/qq_43705330/article/details/125466490