'''
什么是直方图呢?通过直方图你可以对整幅图像的灰度分布有一个整体的了解。直方图的 x 轴
是灰度值(0 到 255),y 轴是图片中具有同一个灰度值的点的数目。
直方图其实就是对图像的另一种解释。一下图为例,通过直方图我们可以对图像的对比度,亮
度,灰度分布等有一个直观的认识。几乎所有的图像处理软件都提供了直方图分析功能。

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

img = cv.imread('timg6.jpg',0)

#使用 OpenCV 统计直方图 函数 cv2.calcHist 可以帮助我们统计一幅图像的直方图可以帮助
#我们统计一幅图像的直方图。
#1. images: 原图像(图像格式为 uint8 或 float32)。当传入函数时应该用中括号 [] 括
#起来,例如:[img]。
#2. channels: 同样需要用中括号括起来,它会告诉函数我们要统计那幅图像的直方图。如果
#输入图像是灰度图,它的值就是 [0];如果是彩色图像的话,
#传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。
#3. mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。但是如果你想统计图像某
#一部分的直方图的话,你就需要制作一个掩模图像,并使用它。(后边有例子)
#4. histSize:BIN 的数目。也应该用中括号括起来,例如:[256]。
#5. ranges: 像素值范围,通常为 [0,256]
#hist = cv.calcHist([img],[0],None,[256],[0,256])

#使用 Numpy 统计直方图 Numpy 中的函数 np.histogram() 也可以帮我们统计直方图。
#img.ravel() 将图像转成一维数组,这里没有中括号。
#hist,bins = np.histogram(img.ravel(),256,[0,256])

plt.hist(img.ravel(),256,[0,256]);
plt.show()

OpenCV学习16-直方图
OpenCV学习16-直方图

'''
多通道(BGR)直方图
'''
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('timg7.jpg')

color = ('b','g','r')

#对一个列表或数组既要遍历索引又要遍历元素时使用内置 enumerrate 函数会有更加直
#接,优美的做法enumerate 会将数组或列表组成一个索引序列。使我们再获取索引和索
#引内容的时候更加方便
#enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索
#引序列,同时列出数据和数据下标,一般用在 for 循环当中。
#>>>seasons = ['Spring', 'Summer', 'Fall', 'Winter']
#>>> list(enumerate(seasons))
#[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
#>>> list(enumerate(seasons, start=1))       # 下标从 1 开始
#[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]


for i,col in enumerate(color):
	'''
	cv2.calcHist(images,channels,mask,histSize,ranges[,hist[,accumulate]])
	1. images: 原图像(图像格式为 uint8 或 float32)。当传入函数时应该
	用中括号 [] 括起来,例如:[img]。
	2. channels: 同样需要用中括号括起来,它会告诉函数我们要统计那幅图
	像的直方图。如果输入图像是灰度图,它的值就是 [0];如果是彩色图像
	的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。
	3. mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。但是如
	果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像,并
	使用它。(后边有例子)
	4. histSize:BIN 的数目。也应该用中括号括起来,例如:[256]。
	5. ranges: 像素值范围,通常为 [0,256]
	'''
	histr = cv.calcHist([img],[i],None,[256],[0,256])
	plt.plot(histr,color = col)
	plt.xlim([0,256])

plt.show()

OpenCV学习16-直方图OpenCV学习16-直方图

'''
使用掩模
要统计图像某个局部区域的直方图只需要构建一副掩模图像。将要统计的
部分设置成白色,其余部分为黑色,就构成了一副掩模图像。然后把这个掩模
图像传给函数就可以了。
'''
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('timg7.jpg')

#创建掩模
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:500] = 255
masked_img = cv.bitwise_and(img,img,mask = mask)

#计算带掩模和不带掩模的直方图
hist_full = cv.calcHist([img],[0],None,[256],[0,256])
hist_mask = cv.calcHist([img],[0],mask,[256],[0,256])

plt.subplot(221), plt.imshow(img, 'gray')
plt.subplot(222), plt.imshow(mask,'gray')
plt.subplot(223), plt.imshow(masked_img, 'gray')
#蓝线是整幅图像的直方图,橙线是掩膜图像的直方图
plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)
plt.xlim([0,256])

plt.show()

OpenCV学习16-直方图

相关文章: