Opencv之直方图

在这里插入图片描述如上图所示,直方图统计的是一张图片中所含不同像素值的个数,横坐标为像素值,纵坐标为此像素值在图中的个数。如像素值为0的像素点在图中有100个,则在直方图中的第一列对应的纵坐标为100。(如果第一列对应的是0像素值的话)
在Opencv中,有专门的函数用来计算每个像素值对应多少像素点:

cv2.calcHist(images,channels,mask,histSize,ranges)
  • images: 原图像图像格式为 uint8 或 float32。当传入函数时应用中括号 [] 括来例如[img]
  • channels: 同样用中括号括来它会告函数我们统幅图像的直方图。如果输入图像是灰度图它的值就是[0];如果是彩色图像 的传入的参数可以是[0]、[1]、[2] 它们分别对应着 B、G、R。
  • mask: 掩模图像。统整幅图像的直方图就把它为 None。但是如果你想统图像某一分的直方图的你就制作一个掩模图像并使用它。
  • histSize:BIN 的数目。也应用中括号括起来。
  • ranges: 像素值范围常为 [0, 256]。
img = cv2.imread('cat.jpg',0) #0表示灰度图
hist = calcHist([img], [0], None, [256], [0, 256])
hist.shape

可以直接用plt.hist()函数绘制直方图:

plt.hist(img.ravel(), 256)
plt.show()

也可以利用得到的hist绘制直方图:

plt.plot(hist)
plt.show()

如果输入图像是彩色的,可以绘制不同通道的直方图:

img = cv2.imread('cat.jpg') 
color = ('b','g','r')
for i, col in enumerate(color):
	histr = cv2.calcHist([img], [i], None, [256], [0, 256])
	plt.plot(histr, color=col)
	plt.xlim([0, 256])

如果只需要对一张图片中的某个区域绘制直方图,则可以使用掩膜操作:

# 创建mask
mask = np.zeros(img.shape[:, 2], np.uint8)
print(mask.shape)
mask[100: 300, 100: 400] = 255
# 导入原始图片
img = cv2.imread('cat.jpg', 0)
# 执行“与”操作,完成掩膜
masked_img = cv2.bitwise_and(img, img, mask=mask)
# 统计直方图
hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])
hist_full = cv2.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中,有专门的函数cv2.equalizeHist()来实现均衡化。

# 原始图像直方图
img = cv2.imread('clahe.jpg',0) #0表示灰度图 #clahe
plt.hist(img.ravel(),256); 
plt.show()
# 均衡化后的直方图
equ = cv2.equalizeHist(img) 
plt.hist(equ.ravel(),256)
plt.show()

但有时,直方图均衡化会分散图中某些部分的信息,如下图:
在这里插入图片描述经过均衡化之后,图片中雕塑的轮廓不易被看清了。
所以,我们需要使用自适应直方图均衡化,将整张图片分成几个部分来分别均衡化,然后再组合在一起。用于生成自适应均衡化图像的函数为:

cv2.createCLAHA(clipLimit, titleGridSize)
  • clipLimit颜色对比度的阈值。
  • titleGridSize进行像素均衡化的网格大小,即在多少网格下进行直方图的均衡化操作。
# 实例化自适应直方图均衡化函数
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
# 进行自适应直方图均衡化
res_clahe = clahe.apply(img)
# 进行图像的展示
res = np.hstack((img, equ, res_clahe))
cv2.imshow('res',res)
cv2.waitKey()
cv2.destroyAllWindows()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

cofisher

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

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

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

打赏作者

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

抵扣说明:

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

余额充值