cv2.calcHist(images, channels, mask, histSize, ranges)
– images:原图像图像格式为uint8或float32,;当传入函数时应用中括号[]括起来;
– channels:同样用中括号括起来;如果输入图像是灰度图,则它的值为[0];如果是彩色图像传入的参数可以使[0][1][2](它们分别对应着BGR);
– mask:掩膜图像;统计整幅图像的直方图,则它的值为None;但若你想统计图像的某一份的直方图,我们制作一个掩膜图像并使用它;
– histSize:BIN的数目;也应用中括号括起来;
– ranges:像素值范围,常为[0, 256]。
查看图像的直方图
import cv2
import numpy as np
import matplotlib.pyplot as plt
if __name__ == '__main__':
#以灰度图的方式读入
img = cv2.imread('./cat.jpg', 0)
#统计灰度图
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
#展示直方图,不展示图片的话,我们就直接用matplotlib展示直方图,img.ravel()将图片转换成一维数组
plt.hist(img.ravel(), 256)
plt.show()
#分别查看3个颜色通道
import cv2
import numpy as np
import matplotlib.pyplot as plt
if __name__ == '__main__':
#以彩色图的方式读入
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])
plt.show()
话不多说,直接上代码。
import cv2
import numpy as np
import matplotlib.pyplot as plt
if __name__ == '__main__':
# 读入一个灰度图
img = cv2.imread('./cat.jpg', 0)
# 展示图像
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 查看图片大小
print(img.shape)
# 定义掩膜
mask = np.zeros(img.shape[:2], np.uint8)
# 要保存什么,就把相应区域置成255
mask[40:120, 40:130] = 255
# 展示掩膜图像
cv2.imshow('mask', mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
masked_img = cv2.bitwise_and(img, img, mask=mask)
# 展示合成结果
cv2.imshow('masked_img', masked_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
直方图均衡化是把原始图像的灰度直方图从比较集中的某个灰度区间变成在更广泛灰度范围内的分布。直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同。
cv2.equalizeHist(img)
返回值为处理好的图像
import cv2
import numpy as np
import matplotlib.pyplot as plt
if __name__ == '__main__':
# 读入一个灰度图
img = cv2.imread('./cat.jpg', 0)
# 展示未均衡化的直方图
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
plt.hist(img.ravel(), 256)
plt.show()
# 直方图均衡化
equ = cv2.equalizeHist(img)
plt.hist(equ.ravel(), 256)
plt.show()
# 展示未均衡化和均衡化之后的图像
res = np.hstack((img, equ))
# 展示图像
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果展示:
未均衡化的直方图:
均衡化之后的直方图:
未均衡化与均衡化之后的图像比较:
通过全局的均衡化,我们发现上图展示的猫脸太暗,缺失了一些细节,这时我们为了解决这个问题,需要使用自适应均衡化,将整幅图像划分成许多小块,在各个小块中分别进行直方图均衡化;同时,为了避免噪声的影响,我们需要设置对比度限制,如果直方图中的bin超过对比度的上限的话,就把其中的像素点均匀分散到其他的bins中,然后再进行直方图均衡化。
import cv2
import numpy as np
import matplotlib.pyplot as plt
if __name__ == '__main__':
# 读入一个灰度图
img = cv2.imread('./cat.jpg', 0)
equ = cv2.equalizeHist(img)
# 自适应直方图均衡化
# 创建一个自适应均衡化对象,并应用到图像上
clahe = cv2.createCLAHE(2.0, (8, 8))
res_clahe = clahe.apply(img)
res = np.hstack((img, equ, res_clahe))
# 展示图像
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()