5.3. 直方图-3:2D直方图

5.3.1. 目标

在这一章中,我们将学习寻找和绘制二维直方图。这将有助于今后的章节。

5.3.2. 介绍

在第一篇文章中,我们计算并绘制了一维直方图。它被称为一维,因为我们只考虑一个特征,即像素的灰度强度值。但是在二维直方图中,考虑两个特征。通常用于寻找颜色直方图,其中两个特征是每个像素的色调和饱和度值。

有一个 python sample in the official samples 已经可以找到颜色直方图了。我们将试图了解如何创建这样一个颜色直方图,这将有助于理解进一步的主题,如直方图反投影。

5.3.3. OpenCV中的二维直方图

它很简单,用同样的函数计算, 化学气相色谱仪() . 对于彩色直方图,我们需要将图像从BGR转换为HSV。(记住,对于一维直方图,我们将BGR转换为灰度)。对于二维直方图,其参数将修改如下:

  • channels = [0,1] because we need to process both H and S plane.

  • bins = [180,256] 180 for H plane and 256 for S plane.

  • range = [0,180,0,256] Hue value lies between 0 and 180 & Saturation lies between 0 and 256.

现在检查下面的代码:

>>> import cv2
>>> import numpy as np
>>>
>>> img = cv2.imread('/cvdata/home.jpg')
>>> hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
>>>
>>> hist = cv2.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
>>> from matplotlib import pyplot as plt
>>> plt.imshow(hist)
<matplotlib.image.AxesImage at 0x7fc610537828>
../_images/sec03-2d-histogram_3_1.png

就这样。

5.3.4. Numpy中的二维直方图

Numpy还为此提供了一个特定的函数: np.histogram2d() . (记住,对于一维直方图,我们使用 直方图()

>>> import cv2
>>> import numpy as np
>>> from matplotlib import pyplot as plt
>>>
>>> img = cv2.imread('/cvdata/home.jpg')
>>> hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
>>> hsv.shape
(384, 512, 3)
>>> h = hsv[0]
>>> s = hsv[1]
>>> v = hsv[2]
>>> hist, xbins, ybins = np.histogram2d(h.ravel(),s.ravel(),[180,256],[[0,180],[0,256]])

第一个参数是H平面,第二个参数是S平面,第三个参数是每一个的bin数,第四个参数是它们的范围。

现在我们可以检查如何绘制这个颜色直方图。

5.3.5. 绘制二维直方图

方法-1:使用cv2.imshow()

我们得到的结果是一个尺寸为180x256的二维数组。所以我们可以像平常一样使用cv2.imshow()函数来显示它们。这将是一个灰度图像,它不会给什么颜色有多大的想法,除非你知道不同颜色的色调值。

方法-2:使用Matplotlib

我们可以使用 matplotlib.pyplot.imshow() 函数用不同的颜色映射绘制二维直方图。它让我们对不同的像素密度有了更好的了解。但这也不能让我们知道第一眼看到的是什么颜色,除非你知道不同颜色的色调值。我还是喜欢这种方法。它简单又好。

注意

使用此函数时,请记住,插值标志应该是 nearest 为了更好的结果。

考虑代码:

>>> import cv2
>>> import numpy as np
>>> from matplotlib import pyplot as plt
>>>
>>> img = cv2.imread('/cvdata/home.jpg')
>>> hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
>>> hist = cv2.calcHist( [hsv], [0, 1], None, [180, 256], [0, 180, 0, 256] )
>>>
>>> plt.imshow(hist,interpolation = 'nearest')
>>> plt.show()
../_images/sec03-2d-histogram_12_0.png

下面是输入图像及其颜色直方图。X轴显示S值,Y轴显示色调。

在直方图中,可以看到H=100和S=200附近的一些高值。它相当于蓝天。同样,在H=25和S=100附近也可以看到另一个峰值。它相当于皇宫的黄色。您可以使用任何图像编辑工具(如GIMP)验证它。

方法三:OpenCV示例样式!!

有一个 sample code for color-histogram in OpenCV-Python2 samples . 如果运行代码,您可以看到直方图也显示了相应的颜色。或者只是输出一个颜色编码的直方图。它的结果非常好(尽管您需要添加更多的行)。

在该代码中,作者在HSV中创建了一个颜色映射。然后把它转换成BGR。生成的直方图图像与此颜色映射相乘。他还使用一些预处理步骤来去除小的孤立像素,从而得到一个良好的直方图。

我把它留给读者来运行代码,分析它,并有你自己的破解方法。下面是与上面相同图像的代码输出:

你可以在直方图中清楚地看到有什么颜色,蓝色在那里,黄色在那里,还有一些白色由于棋盘在那里。很好!!!

5.3.6. 额外资源

5.3.7. 练习