OpenCV-Python -- Histograms - 3 : 2D Histograms

学习目标

这一节,我们将学习寻找和绘制2D直方图,对后面的章节非常有用。

简介

在直方图系列的第一节,我们计算并绘制了一维直方图。之所以称之为一维,是因为我们仅仅考虑一个特征(图像的灰度值)。但是,在二维直方图中,我们考虑2个特征。通常情况下,在计算彩色直方图的时候,考虑的2个特征为每个像素的色度和饱和度(Hue&Saturation)。

2D Histogram in OpenCV

使用的函数依然是:cv2.calcHist(). 对于彩色直方图,我们需要将图像进行转换(BGR->HSV),在1D直方图中,我们将彩色图转换为灰度图(Grayscale)。2D直方图中,参数修改如下:

  • channels = [0, 1],因为我们需要处理HS平面。
  • bins = [180, 256],180是H通道,256是S通道。
  • range = [0, 180, 0, 256],Hue的范围为【0,180】,Saturation的范围【0,256】。

看下面的例子,计算2D直方图:

import cv2
import numpy as np

img = cv2.imread('home.jpg')
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

hist = cv2.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])

2D Histogram in Numpy

Numpy计算2D直方图的函数为:np.histogram2d()(1D直方图的函数为,np.histogram())。计算代码如下:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('home.jpg')
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
h, s = hsv[:, :, 0], hsv[:, :, 1]
hist, xbins, ybins = np.histogram2d(h.ravel(),s.ravel(),[180,256],[[0,180],[0,256]])

Plotting 2D Histograms

方法1:cv2.imshow()

2D直方图返回的是大小为180x256的数组。所以,我们可以使用cv2.imshow()显示。但是显示的是灰度图,并不能反映彩色信息,除非知道不同颜色的Hue值。

方法2:Matplotlib

可以使用不同的颜色图绘制2D直方图,函数为matplotlib.pyplot.imshow()。这样可以方便得到不同像素强度。但是,同样无法得到具体的颜色信息,除非知道不同颜色的Hue值。

注意,当使用该函数时,插值必须使用nearsest,这样可以达到更好的效果。

代码

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('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()

下图是运行结果,X轴表示 S 值,Y轴表示H值,如下:
在这里插入图片描述
在这里插入图片描述
从图中可以看出,较高的值在 H=100和S=200附近,应该对应的是天空的蓝色。另外的高峰在 H=25和S=100附近,应该对应的是黄色的墙面(因为我们提前知道H值和S值对应的颜色,上面的论述中也强调了这一点)。

方法3:OpenCV sample style

上面我们说过,使用OpenCV绘制的2D直方图是灰度图,无法显示特定的颜色。那么应该操作如下:在HSV空间创建颜色图。然后转为BGR。然后将CV计算的直方图乘以该颜色图。当然也有一些预处理,比如移除孤立的像素。

下面是结果,可以看出,从2D直方图就可以看出对应图像中的区域:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值