Python实现二维直方图:OpenCV与Numpy详解
本文深入解析Python中二维直方图的实现方法,重点对比OpenCV的cv2.calcHist()与Numpy的np.histogram2d()函数。通过HSV色彩空间转换、参数设置及代码示例,展示如何计算并可视化图像的颜色分布,适用于图像处理和颜色特征提取场景。
前言
仅统计像素灰度值的一维特征称为一维直方图。若需同时统计像素的色相与饱和度以分析图像颜色分布,则需使用二维直方图。
一、OpenCV中的二维直方图
在OpenCV中,仍使用cv2.calcHist()函数来计算图像的颜色直方图,但其参数配置方式与一维情况有所不同。
cv2.calcHist()函数的基本调用格式如下:
hist =cv2.calcHist(image, channels, mask, histSize, ranges)
image参数指定的原图像需先从BGR色彩空间转换为HSV色彩空间,实际传入的参数需用方括号包裹。
当channels参数设置为[0,1]时,表示同时处理色相(Hue)和饱和度(Saturation)两个通道。
当histSize参数设置BINS值为[180,256]时,表示色相通道分为180个区间,饱和度通道分为256个区间。
当ranges参数设置为[0,180,0,256]时,表示色相的取值范围为[0,180],饱和度的取值范围为[0,256](注:原文此处写作2565,疑为笔误,通常饱和度最大值为255或256,此处保留原文数值描述但建议核实)。
cv2.calcHist()函数返回的颜色直方图数据可直接通过cv2.imshow()函数进行显示。
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('XIAN.jpg')
cv2.namedWindow('orininal', cv2.WINDOW_NORMAL)
cv2.imshow('orininal', img)
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
hist = cv2.calcHist([img2], [0, 1], None, [180, 256], [0,180,0,256])
cv2.namedWindow('2DHist', cv2.WINDOW_NORMAL)
cv2.imshow('2DHist', hist)
cv2.waitKey(0)
cv2.destroyAllWindows()
plt.imshow(hist, interpolation = 'nearest') # 绘制颜色直方图
plt.show() # 显示颜色直方图

cv2.calcHist()返回的颜色直方图是一个大小为180*256的二维数组。若直接使用cv2.imshow()显示,结果为灰度图像,无法直接直观呈现颜色的分布情况。
为了更清晰地展示颜色分布,可以使用matplotlib.pyplot.imshow()函数绘制带有不同颜色的二维直方图。

二、Numpy中的二维直方图
Numpy库提供了np.histogram2d()函数用于计算二维直方图,其基本调用格式如下:
hist, xedges, yedges = np.histogram2d(x, y, bins, range)
hist为返回的直方图数据数组。
xedges为返回的x轴(色相)直方图的BINS边界值数组。
yedges为返回的y轴(饱和度)直方图的BINS边界值数组。
x和y分别为原图对应通道转换后的一维数组数据。
bins为BINS的值,例如[180,256],定义了两个维度的区间数量。
range为像素值的取值范围,格式示例为[[0, 180],[0, 256]]。
img = cv2.imread('building.jpg')
cv2.imshow('orininal', img)
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(img2)
hist, x, y = np.histogram2d(h.ravel(), s.ravel(), [180, 256], [[0, 180],[0, 256]])
cv2.imshow('2DHist', hist)
cv2.waitKey(0)
cv2.destroyAllWindows()
plt.imshow(hist, interpolation = 'nearest')
plt.show()

同样可以使用matplotlib.pyplot.imshow()函数绘制具有不同颜色的二维直方图,以可视化颜色分布。

三、直方图示例
1、使用Numpy函数计算直方图
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('home.jpg')
plt.figure(figsize = (25,25))
imgrgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.subplot(2, 2, 1)
plt.title('Original')
plt.axis('off')
plt.imshow(imgrgb)
histb, e1 = np.histogram(img[0].ravel(), 256, [0, 255]) #计算B通道直方图
histg, e2 = np.histogram(img[1].ravel(), 256, [0, 255]) #计算G通道直方图
histr, e3 = np.histogram(img[2].ravel(), 256, [0, 255]) #计算R通道直方图
plt.subplot(2, 2, 2)
plt.plot(histb, color = 'b')
plt.plot(histg, color = 'g')
plt.plot(histr, color = 'r')
plt.title('Hist')
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #转换色彩空间为HSV
h, s, v = cv2.split(img2)
hist, x, y=np.histogram2d(h.ravel(), s.ravel(), [180, 256], [[0, 180], [0, 256]]) #计算颜色直方图
plt.subplot(2, 2, 3)
plt.title('2Dhist') #设置子图窗口标题
plt.imshow(hist, interpolation = 'nearest',cmap = 'gray') #绘制颜色直方图
plt.show() #显示颜色直方图

2、使用OpenCV函数计算直方图
# 2.使用OpenCV函数计算直方图
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('flower.jpg')
plt.figure(figsize = (25,25))
imgrgb=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.subplot(2, 2, 1)
plt.imshow(imgrgb)
plt.title('Original')
plt.axis('off')
histb = cv2.calcHist([img], [0], None, [256], [0,255]) #计算B通道直方图
histg = cv2.calcHist([img], [1], None, [256], [0,255]) #计算G通道直方图
histr = cv2.calcHist([img], [2], None, [256], [0,255]) #计算R通道直方图
plt.subplot(2, 2, 2)
plt.plot(histb, color= 'b')
plt.plot(histg, color= 'g')
plt.plot(histr, color= 'r')
plt.title('Hist')
img2=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
hist = cv2.calcHist([img2], [0, 1], None, [180, 256], [0, 180, 0, 256])
plt.subplot(2, 2, 3)
plt.title('2Dhist') #设置子图窗口标题
plt.imshow(hist,interpolation = 'nearest',cmap = 'gray') #绘制颜色直方图
plt.show() #显示颜色直方图

到此这篇关于深入了解Python二维直方图的文章就介绍到这了,更多相关Python 二维直方图内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













