OpenCV直方图的比较

「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战

直方图的比较

我们已经在《灰度直方图详解》中学习了如何使用 cv2.calcHist() 函数计算直方图,并且了解了直方图的一些使用示例。

本节,我们将介绍 OpenCV 提供的另一个与直方图相关的函数是 cv2.compareHist(),该函数可用于计算两个直方图的匹配程度。由于直方图反映了图像中像素值的强度分布,因此该函数也可以用于比较图像,但是由于直方图仅显示统计信息,而不显示像素的位置。因此,图像比较的常用方法是将图像划分为一定数量的区域(通常大小相同),计算每个区域的直方图,最后将所有直方图连接起来,创建图像的特征表示。为了简单起见,示例将仅使用一个区域(完整图像),并不会将图像划分多个区域。

cv2.compareHist() 函数的用法:

cv2.compareHist(H1, H2, method)
复制代码

这里,H1H2 是被比较的直方图,method表示度量方法。OpenCV 提供了四种不同的度量方法( method )来计算匹配程度:

度量方法 解释
cv2.HISTCMP_CORREL 计算两个直方图之间的相关性,此指标返回 [-1, 1] 范围内的值,其中 1 表示完美匹配,-1 表示完全不匹配
cv2.HISTCMP_CHISQR 计算两个直方图之间的卡方距离,此指标返回 [0, unbounded] 范围内的值,其中 0 表示完美匹配,而不匹配则使用 unbounded 表示
cv2.HISTCMP_INTERSECT 计算两个直方图之间的交集,如果直方图被归一化,则该指标返回范围 [0, 1] 内的值,其中 1 表示完全匹配,0 表示完全不匹配
cv2.HISTCMP_BHATTACHARYYA 计算两个直方图之间的 Bhattacharyya 距离。此指标返回 [0, 1] 范围内的值,其中 0 是完美匹配,1 完全不匹配

为了对比不同的度量方法,我们首先图像并对其进行变换,然后使用所有度量方法计算这些图像和测试图像之间的相似度。

# 加载图像
image = cv2.imread('example.png')
# 转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

M = np.ones(gray_image.shape, dtype='uint8') * 30
# 所有像素值加上 30
added_image = cv2.add(gray_image, M)
# 所有像素值减去 30
subtracted_image = cv2.subtract(gray_image, M)
# 使用模糊滤镜
blurred_image = cv2.blur(gray_image, (10,10))
def load_all_test_images():
    images = []
    images.append(gray_image)
    images.append(added_image)
    images.append(subtracted_image)
    images.append(blurred_image)
    return images
复制代码

使用四种不同的度量方法计算这些图像和测试图像之间的相似度:

for img in test_images:
    # 计算直方图
    hist = cv2.calcHist([img], [0], None, [256], [0, 256])
    # 直方图归一化
    hist = cv2.normalize(hist, hist, norm_type=cv2.NORM_L1)
    hists.append(hist)
# 使用 cv2.HISTCMP_CORREL 度量方法
gray_gray = cv2.compareHist(hists[0], hists[1], cv2.HISTCMP_CORREL)
gray_grayblurred = cv2.compareHist(hists[0], hists[1], cv2.HISTCMP_CORREL)
gray_addedgray = cv2.compareHist(hists[0], hists[2], cv2.HISTCMP_CORREL)
gray_subgray = cv2.compareHist(hists[0], hists[3], cv2.HISTCMP_CORREL)
# 使用 cv2.HISTCMP_CHISQR 度量方法
gray_gray = cv2.compareHist(hists[0], hists[0], cv2.HISTCMP_CHISQR)
gray_grayblurred = cv2.compareHist(hists[0], hists[1], cv2.HISTCMP_CHISQR)
gray_addedgray = cv2.compareHist(hists[0], hists[2], cv2.HISTCMP_CHISQR)
gray_subgray = cv2.compareHist(hists[0], hists[3], cv2.HISTCMP_CHISQR)
# 使用 cv2.HISTCMP_INTERSECT 度量方法
gray_gray = cv2.compareHist(hists[0], hists[0], cv2.HISTCMP_INTERSECT)
gray_grayblurred = cv2.compareHist(hists[0], hists[1], cv2.HISTCMP_INTERSECT)
gray_addedgray = cv2.compareHist(hists[0], hists[2], cv2.HISTCMP_INTERSECT)
gray_subgray = cv2.compareHist(hists[0], hists[3], cv2.HISTCMP_INTERSECT)
# 使用 cv2.HISTCMP_BHATTACHARYYA 度量方法
gray_gray = cv2.compareHist(hists[0], hists[0], cv2.HISTCMP_BHATTACHARYYA)
gray_grayblurred = cv2.compareHist(hists[0], hists[1], cv2.HISTCMP_BHATTACHARYYA)
gray_addedgray = cv2.compareHist(hists[0], hists[2], cv2.HISTCMP_BHATTACHARYYA)
gray_subgray = cv2.compareHist(hists[0], hists[3], cv2.HISTCMP_BHATTACHARYYA)
复制代码

程序的输出如下所示:

直方图的比较

从上图可以看出,img 1 所有指标都完美匹配,因为它是相同的图像,img 2 也具有较好的匹配指标,这是因为 img 2 是查询图像的平滑版本,而 img 3img 4 给出的匹配程度很差,这是因为直方图发生了偏移。

相关链接

OpenCV直方图基本概念

OpenCV灰度直方图详解

OpenCV颜色直方图与直方图自定义可视化

Guess you like

Origin juejin.im/post/7061390224688939044