opencv(29) 直方图之三:直方图对比

图像直方图是反映一个图像像素分布的统计表,其实横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的。纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比。

图像是由像素构成,因为反映像素分布的直方图往往可以作为图像一个很重要的特征。在实际工程中,图像直方图在特征提取、图像匹配等方面都有很好的应用。

直方图比较

  1. 图像相似度比较:如果我们有两张图像,并且这两张图像的直方图一样,或者有极高的相似度,那么在一定程度上,我们可以认为这两幅图是一样的,这就是直方图比较的应用之一。
  2. 分析图像之间关系:两张图像的直方图反映了该图像像素的分布情况,可以利用图像的直方图,来分析两张图像的关系。

1 原理

要比较两个直方图(H1H2 ), 首先必须要选择一个衡量直方图相似度的 对比标准

OpenCV 函数 compareHist 执行了具体的直方图对比的任务。该函数提供了4种对比标准来计算相似度:

相关性(Correlation)比较 ( cv2. HISTCMP_CORREL )

卡方(Chi-Square)比较(cv2.HISTCMP_CHISQR)

(Intersection)比较(cv2. HISTCMP_INTERSECT)

巴氏(Bhattacharyya)距离比较( cv2_ HISTCMP_BHATTACHARYYA )

2 cv2.compareHist()函数

原型cv2.compareHist(H1, H2, method)

参数:

  1. H1,H2:分别为要比较图像的直方图
  2. method:比较方式

cv2.HISTCMP_CORREL——相关性比较,值越大,相关度越高,最大值为1,最小值为0

cv2.HISTCMP_CHISQR——卡方比较,值越小,相关度越高,最大值无上界,最小值0

cv2.HISTCMP_BHATTACHARYYA——巴氏距离比较,值越小,相关度越高,最大值为1,最小值为0

cv2. HISTCMP_INTERSECT

3 示例

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt


def create_rgb_hist(image):
    """"创建 RGB 三通道直方图(直方图矩阵)"""
    h, w, c = image.shape
    # 创建一个(16*16*16,1)的初始矩阵,作为直方图矩阵
    # 16*16*16的意思为三通道每通道有16个bins
    rgbhist = np.zeros([16 * 16 * 16, 1], np.float32)
    bsize = 256 / 16
    for row in range(h):
        for col in range(w):
            r = image[row, col, 0]
            g = image[row, col, 1]
            b = image[row, col, 2]
            # 人为构建直方图矩阵的索引,该索引是通过每一个像素点的三通道值进行构建
            index = int(b / bsize) * 16 * 16 + int(g / bsize) * 16 + int(r / bsize)
               # 该处形成的矩阵即为直方图矩阵
            rgbhist[int(index), 0] += 1
    plt.ylim([0, 10000])
    plt.grid(color='r', linestyle='--', linewidth=0.5, alpha=0.3)
    return rgbhist

def hist_compare(image1, image2):
    """直方图比较函数"""
    # 创建第一幅图的rgb三通道直方图(直方图矩阵)
    hist1 = create_rgb_hist(image1)
    # 创建第二幅图的rgb三通道直方图(直方图矩阵)
    hist2 = create_rgb_hist(image2)
    # 进行三种方式的直方图比较
    match1 = cv.compareHist(hist1, hist2, cv.HISTCMP_BHATTACHARYYA)
    match2 = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL)
    match3 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR)
    print("巴氏距离:%s, 相关性:%s, 卡方:%s" %(match1, match2, match3))


img1 = cv.imread("C:/Users/liyou/xxx/lena.jpg")
img1 = cv2.merge((img[:,:,2],img[:,:,1],img[:,:,0]))
imgR,imgG,imgB =cv2.split(img1)

# 【第一步:形成img2(使用自适应直方图均衡化)】
# 【实例化自适应直方图均衡化函数】
clahe = cv2.createCLAHE(clipLimit=2.0,  tileGridSize=(8, 8))


# 【第二步:进行自适应直方图均衡化】
retR = clahe.apply(imgR)
retG = clahe.apply(imgG)
retB = clahe.apply(imgB)
img2 = cv2.merge([retR,retG,retB])

# 【第三步:使用plt.hist绘制像素直方图和图像显示】
# 【绘制原图】
fig = plt.figure(figsize=(25.6,4.8))
plt.subplot(1,4,1),plt.imshow(img1)
plt.title('原图',fontsize=20), plt.xticks([]), plt.yticks([])
# 【绘制直方图均衡化后的图像】
plt.subplot(1,4,3),plt.imshow(img2)
plt.title('直方图均衡化',fontsize=20), plt.xticks([]), plt.yticks([])
# 【绘制原图的R,G,B直方图】
plt.subplot(1,4,2)
plt.title('R,G,B 原图直方图',fontsize=20)
plt.plot(create_rgb_hist(img1))
# 【绘制直方图均衡化后的图像的R,G,B直方图】
plt.subplot(1,4,4)
plt.title('R,G,B 均衡化后的直方图',fontsize=20)
plt.plot(create_rgb_hist(img2))
# 【比较直方图】
hist_compare(img1, img2)
plt.show()

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值