利用OpenCV的函数compareHist()对图像的直方图进行相似性比较
图像的直方图表示图像的灰度值统计特性,有时可以通过比较两幅图像的直方图来衡量两幅图像的相似程度。
虽然两幅图像的直方图分布相似不代表两幅图像相似,但两幅图像相似,则两幅图像的的直方图分布一定相似。例如,通过插值对图像进行缩放后,图像的直方图虽然不会与之前完全一致,但是两者之间一定具有很高的相似性,因而可以通过比较两幅图像的直方图分布的相似性对图像进行初步的筛选与识别。
OpenCV提供了用于比较两幅图像直方图相似性的函数compareHist()。
函数compareHist()的原型如下:
- double cv::compareHist(InputArray H1,
- InputArray H2,
- int method )
复制代码- retval=cv.compareHist(H1, H2, method)
复制代码
从上面的原型可以看出,函数compareHist的使用是很简单的,关键在于知道参数method有哪些可选的比较方法。
参数method的各个取值及代表的意义见下表所示:
![](http://pic1.hhai.cc/pic1/2023/2023-01/001/44.png)
当method取HISTCMP_CORREL时,如果两幅图像的直方图完全一致,则计算值为1;如果两幅图像的直方图完全不相关,则计算值为0。
当method取HISTCMP_CHISQR 时,如果两幅图像的直方图完全一致,则计算值为0;两幅图像的相似性越低,计算值越大。
当method取HISTCMP_INTERSECT时,数值越大,相似性越高;数值越小,相似性越低。
当method取HISTCMP_BHATTACHARYYA 时,如果两幅图像的直方图完全一致,则计算值为0;两幅图像的相似性越低,计算值越大。
当method取HISTCMP_CHISQR_ALT 时,如果两幅图像的直方图完全一致,则计算值为0;两幅图像的相似性越低,计算值越大。
当method取HISTCMP_KL_DIV 时,如果两幅图像的直方图完全一致,则计算值为0;两幅图像的相似性越低,计算值越大。
Python示例代码如下:
[Python] 纯文本查看 复制代码 # -*- coding: utf-8 -*-
# 出处:昊虹AI笔记网(hhai.cc)
# 用心记录计算机视觉和AI技术
# 博主微信/QQ 2487872782
# QQ群 271891601
# 欢迎技术交流与咨询
# OpenCV的版本为4.4.0
import cv2 as cv
import math
import sys
if __name__ == '__main__':
# 读取图像并判断是否读取成功
img1 = cv.imread('E:/material/images/2023/2023-01/hand1.jpg', 0)
img2 = cv.imread('E:/material/images/2023/2023-01/hand2.jpg', 0)
img3 = cv.imread('E:/material/images/2023/2023-01/circle.jpg', 0)
if img1 is None:
print('Failed to read img1.')
sys.exit()
if img2 is None:
print('Failed to read img2.')
sys.exit()
if img3 is None:
print('Failed to read img3.')
sys.exit()
cv.imshow('img1', img1)
cv.imshow('img2', img2)
cv.imshow('img3', img3)
# 计算图像直方图
img1_hist = cv.calcHist([img1], [0], None, [255], [0, 256])
img2_hist = cv.calcHist([img2], [0], None, [255], [0, 256])
img3_hist = cv.calcHist([img3], [0], None, [255], [0, 256])
# 进行直方图比较
result1 = cv.compareHist(img1_hist, img1_hist, method=cv.HISTCMP_CORREL)
result2 = cv.compareHist(img1_hist, img2_hist, method=cv.HISTCMP_CORREL)
result3 = cv.compareHist(img1_hist, img3_hist, method=cv.HISTCMP_CORREL)
# 对比图结果进行近似值处理
round_result1 = round(abs(result1), 2)
round_result2 = round(abs(result2), 2)
round_result3 = round(abs(result3), 2)
cv.waitKey(0)
cv.destroyAllWindows()
运行结果如下:
![](http://pic1.hhai.cc/pic1/2023/2023-01/001/45.png)
![](http://pic1.hhai.cc/pic1/2023/2023-01/001/46.png)
C++代码略。
|