【OpenCV学习笔记29】- OpenCV 中的直方图 - 直方图 - 3:2D 直方图

这是对于 OpenCV 官方文档中 图像处理 的学习笔记。学习笔记中会记录官方给出的例子,也会给出自己根据官方的例子完成的更改代码,同样彩蛋的实现也会结合多个知识点一起实现一些小功能,来帮助我们对学会的知识点进行结合应用。
如果有喜欢我笔记的请麻烦帮我关注、点赞、评论。谢谢诸位。

学习笔记:
学习笔记目录里面会收录我关于OpenCV系列学习笔记博文,大家如果有什么不懂的可以通过阅读我的学习笔记进行学习。
【OpenCV学习笔记】- 学习笔记目录

内容

  • 查找和绘制2D直方图

介绍

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

已经有一个python样本( samples/python/color_histogram.py )用于查找颜色直方图。我们将尝试了解如何创建这种颜色直方图,这对于理解诸如直方图反投影之类的更多主题将很有用。

OpenCV中的2D直方图

它非常简单,并且使用相同的函数 cv.calcHist() 进行计算。对于颜色直方图,我们需要将图像从BGR转换为HSV。(请记住,对于一维直方图,我们从BGR转换为灰度)。对于2D直方图,其参数将进行如下修改:

  • channels = [0,1], 因为我们需要同时处理H和S平面。
  • bins = [180,256] 对于H平面为180,对于S平面为256。
  • range= [0,180,0,256] 色相值介于0和180之间,饱和度介于0和256之间。

示例代码:

# OpenCV 中的直方图
# 直方图 - 3:2D 直方图
# OpenCV中的2D直方图
import numpy as np
import cv2 as cv
img = cv.imread('../image/3.9.4-1.png')
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
hist = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])

Numpy中的2D直方图

Numpy还为此提供了一个特定功能:np.histogram2d() 。(请记住,对于一维直方图,我们使用了 np.histogram() )。

示例代码:

# OpenCV 中的直方图
# 直方图 - 3:2D 直方图
# Numpy中的2D直方图
import numpy as np
import cv2 as cv

img = cv.imread('home.jpg')
assert img is not None, "file could not be read, check with os.path.exists()"
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
# 将 hsv 图像拆分成三个单通道图像,分别对应于色相(H)、饱和度(S)和明度(V)
h, s, v = cv.split(hsv)
hist, xbins, ybins = np.histogram2d(h.ravel(), s.ravel(), [180, 256], [[0, 180], [0, 256]])

注意: 官方文档少了 h, s, v = cv.split(hsv) 对hsv图像的通道拆分,会让示例代码中的 h.ravel(),s.ravel() 显的有点莫名其妙,因为没有对应变量。

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

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

绘制2D直方图

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

我们得到的结果是尺寸为180x256的二维数组。因此,可以使用 cv.imshow() 函数像平常一样显示它们。它将是一幅灰度图像,除非您知道不同颜色的色相值,否则不会对其中的颜色有太多了解。

示例代码:

# OpenCV 中的直方图
# 直方图 - 3:2D 直方图
# 绘制2D直方图
# 方法-1:使用 cv.imshow()
import numpy as np
import cv2 as cv

img = cv.imread('../image/3.10.3-1.png')
assert img is not None, "file could not be read, check with os.path.exists()"
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
# 将 hsv 图像拆分成三个单通道图像,分别对应于色相(H)、饱和度(S)和明度(V)
h, s, v = cv.split(hsv)
hist, xbins, ybins = np.histogram2d(h.ravel(), s.ravel(), [180, 256], [[0, 180], [0, 256]])
cv.imshow("hist", hist)
cv.waitKey(0)
cv.destroyAllWindows()

效果图:
在这里插入图片描述

方法-2:使用Matplotlib

我们可以使用 matplotlib.pyplot.imshow() 函数绘制具有不同颜色图的2D直方图。它使我们对不同的像素密度有了更好的了解。但是,这也并不能使我们一眼就能知道是什么颜色,除非您知道不同颜色的色相值。我还是更喜欢这种方法。它简单而更好。

注意: 使用此功能时,请记住,插值标记应最接近以获得更好的结果。

示例代码:

# OpenCV 中的直方图
# 直方图 - 3:2D 直方图
# 绘制2D直方图
# 方法-2:使用Matplotlib
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('../image/3.10.3-1.png')
cv.imshow("img", img)
cv.waitKey(0)
assert img is not None, "file could not be read, check with os.path.exists()"
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
hist = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
plt.imshow(img)
plt.imshow(hist, interpolation='nearest')
plt.show()
cv.destroyAllWindows()

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

效果图:
在这里插入图片描述

方法3:OpenCV示例样式

OpenCV-Python2示例中有一个颜色直方图的示例代码( samples/python/color_histogram.py )。如果运行代码,则可以看到直方图也显示了相应的颜色。或者简单地,它输出颜色编码的直方图。其结果非常好(尽管您需要添加额外的线束)。

在该代码中,作者在HSV中创建了一个颜色图。然后将其转换为BGR。将所得的直方图图像与此颜色图相乘。他还使用一些预处理步骤来删除小的孤立像素,从而获得良好的直方图。

我将它留给读者来运行代码,对其进行分析并拥有自己的解决方法。下面是与上面相同的图像的代码输出:
在这里插入图片描述
您可以在直方图中清楚地看到存在什么颜色,那里是蓝色,那里是黄色,并且由于棋盘而有些白色。不错!

  • 28
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜七天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值