【问题标题】:Difference in histograms of a colored image using plt.plot v/s plt.hist [Python]使用 plt.plot 与 plt.hist [Python] 的彩色图像直方图的差异
【发布时间】:2021-08-23 13:30:23
【问题描述】:

我使用下面的代码通过 2 种方法生成彩色图像的直方图:

方法一:-

  1. 使用 cv2.calcHist() 函数计算频率
  2. 使用 plt.plot() 生成频率的线图

方法二:-

  1. 使用 plt.hist() 函数计算并生成直方图(我添加了 bin=250 以便 2 个直方图一致)

观察:两个直方图大致相似。第一个直方图(使用 plt.plot)看起来很平滑。然而,第二个直方图(使用 plt.hist)有额外的尖峰和下降。

问题:由于图像只有 int 值,因此不应出现不一致的分箱。 histogram-2 中这些额外的峰值和下降的原因是什么?

    blue_bricks = cv2.imread('Computer-Vision-with-Python/DATA/bricks.jpg')
    
    fig = plt.figure(figsize=(17,10))
    color = ['b','g','r']
    
    # Histogram Type-1
    fig.add_subplot(2,2,1)
    
    for i,c in enumerate(color): 
        hist = cv2.calcHist([blue_bricks], mask=None, channels=[i], histSize=[256], ranges=[0,256])
        plt.plot(hist,color=c)    
    plt.title('Histogram-1')
    
    # Histogram Type-2
    fig.add_subplot(2,2,2)
    
    for i,c in enumerate(color):
        plt.hist(blue_bricks[:,:,i].flatten(),color=c, alpha=0.5, bins=250)
    plt.title('Histogram-2')

【问题讨论】:

    标签: python-3.x opencv matplotlib computer-vision opencv-python


    【解决方案1】:

    bins=250 在最低值和最高值之间创建 251 个等距的 bin 边缘。这些与离散值不一致。当最高和最低之间的差异大于 250 时,一些 bin 将是空的。当差值小于 250 时,一些 bin 将获取两个相邻数字的值,从而产生峰值。此外,在叠加直方图时,所有直方图都使用完全相同的 bin 边缘很方便。

    您需要 bin 恰好在整数值之间,设置 bins=np.arange(-0.5, 256, 1) 可以实现这一点。或者,您可以使用 seaborn 的histplot(...., discrete=True)

    这里有一些数字较小的代码来说明正在发生的事情。

    import matplotlib.pyplot as plt
    import numpy as np
    
    fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, figsize=(12, 3))
    
    for ax in (ax1, ax2, ax3, ax4):
        if ax in [ax1, ax3]:
            x = np.arange(1, 10)
        else:
            x = np.arange(1, 12)
        if ax in [ax1, ax2]:
            bins = 10
        else:
            bins = np.arange(0.5, x.max() + 1, 1)
        _, bin_edges, _ = ax.hist(x, bins=bins, ec='white', lw=2)
        ax.vlines(bin_edges, 0, 2.5, color='crimson', ls='--')
        ax.scatter(x, [2.2] * len(x), color='lime', s=50)
        ax.set_title((f"{bins} bins" if type(bins) == int else "discrete bins") + f', {len(x)} values')
        ax.set_xticks(x)
        ax.set_yticks([0, 1, 2])
    plt.tight_layout()
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 2021-07-08
      • 1970-01-01
      • 1970-01-01
      • 2014-12-31
      • 2011-06-30
      • 2011-11-30
      • 2017-12-03
      • 1970-01-01
      • 2014-12-18
      相关资源
      最近更新 更多