import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
def plot_demo(image):
# image.ravel()将图像展开为一行, 256为bins数量, [0, 256]为x轴范围
# (x, bins = None, range)
# print(image.ravel().shape)
plt.hist(image.ravel(), 256, [0, 256])
plt.show()
def image_hist(image):
color = ("blue", "green", "red")
for i, color in enumerate(color):
# 计算出直方图
# (images, channels, mask, histSize(有多少个bin), ranges: x轴范围
# hist 是一个 256x1 的数组, 每一个值代表了与该灰度值对应的像素点数目.
# 统计一张图片某个通道的像素点值的分布情况
hist = cv.calcHist(image, [i], None, [256], [0, 256])
print(hist.shape) # (256, 1)
# 画线 ([x], [y], color) x值可以省略 默认[0,1..,N-1]递增
plt.plot(hist, color)
# 设置x轴的数值显示范围
plt.xlim([0, 256])
plt.show()
def equalHist_demo(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("gray", gray)
# 全局直方图均衡化, 用于增加图像对比度
dst = cv.equalizeHist(gray)
cv.imshow("equalHist_demo", dst)
plot_demo(dst)
"""
局部直方图均衡化
把整个图像分成许多小块(比如按8*8作为一个小块),
那么对每个小块进行均衡化。
这种方法主要对于图像直方图不是那么单一的(比如存在多峰情况)图像比较实用
"""
# 局部直方图均衡化
# 图片按照不重叠每块(8 * 8)分割
# clipLimit阈值为限制对比度值, 超过该阈值的值会被裁剪, 裁剪的部分会均匀的分布到其他值上
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
clahe_dst = clahe.apply(gray)
cv.imshow("clahe", clahe_dst)
# 创建直方图
def create_rgb_demo(image):
h, w, c = image.shape
# 每个通道用16个bin表示
# 三个通道, 不同的颜色组合就需要就有16*16*16个bin表示
rgbHist = np.zeros([16*16*16, 1], np.float32)
bsize = 256 / 16 # 一个bin的大小
for row in range(h):
for col in range(w):
# 取出此点的bgr分别对应的值
b = image[row, col, 0]
g = image[row, col, 1]
r = image[row, col, 2]
# index即此时这个三通道的组合在rgbHist中的位置, 对其统计值加一
# 由于每个通道的值(0~255)都有16个bin表示,所以要px/bsize即此时的像素值属于哪个bin
index = np.int(b/bsize)*16*16 + np.int(g/bsize)*16 + np.int(r/bsize)
rgbHist[np.int(index), 0] += 1
return rgbHist
# 利用直方图比较相似性, 用巴氏和相关性比较好
def hist_compare(image1, image2):
hist1 = create_rgb_demo(image1)
hist2 = create_rgb_demo(image2)
# (hist1, hist2, 比较方法)
match1 = cv.compareHist(hist1, hist2, method=cv.HISTCMP_BHATTACHARYYA)
match2 = cv.compareHist(hist1, hist2, method=cv.HISTCMP_CORREL)
match3 = cv.compareHist(hist1, hist2, method=cv.HISTCMP_CHISQR)
print("巴式距离:%s, 相关性:%s, 卡方:%s" % (match1, match2, match3))
main
if __name__ == '__main__':
src = cv.imread("./images/CrystalLiu1.jpg")
# src = cv.imread("./images/rice.png")
# cv.imshow("demo", src)
# plot_demo(src)
# image_hist(src)
# equalHist_demo(src)
image1 = cv.imread("./images/19_25_26.jpg")
image2 = cv.imread("./images/19_25_28.jpg")
cv.imshow("img1", image1)
cv.imshow("img2", image2)
hist_compare(image1, image2)
cv.waitKey(0)
cv.destroyAllWindows()