Python OpenCV 图像处理之直方图的应用,取经之旅第 26 天

举报
梦想橡皮擦 发表于 2021/09/18 09:22:25 2021/09/18
【摘要】 Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。 基础知识铺垫上篇博客 Python OpenCV 图像处理之图像直方图,取经之旅第 25 天中,我们重点学习了直方图的绘制方法与应用,本篇博客继续对直方图进行分析。本篇博客咱们首先学习一下,如何用直方图去比较两幅图片的相似性。通过 cv2.compareHist 函数计算图片的相似度,在今天的学习中,橡皮擦并没有 ...

Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。

基础知识铺垫

上篇博客 Python OpenCV 图像处理之图像直方图,取经之旅第 25 天中,我们重点学习了直方图的绘制方法与应用,本篇博客继续对直方图进行分析。

本篇博客咱们首先学习一下,如何用直方图去比较两幅图片的相似性。

通过 cv2.compareHist 函数计算图片的相似度,在今天的学习中,橡皮擦并没有 get 到一个特别好的场景,故本部分从语法角度进行学习。

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:十字交叉,值越大越相似。

先比较灰度图的,运行下述代码即可。

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


def create_gray_hist(image):
    # 创建一个灰度直方图
    img = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    hist = cv.calcHist([img], [0], None, [256],  [0, 256])
    return hist


def hist_compare(image1, image2):

    # 第一幅图的灰度图直方图
    hist1 = create_gray_hist(image1)
    # 第二幅图的灰度图直方图
    hist2 = create_gray_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)
    match4 = cv.compareHist(hist1, hist2, cv.HISTCMP_INTERSECT)
    print("巴氏距离:%s, 相关性:%s, 卡方:%s, 十字交叉:%s" % (match1, match2, match3, match4))


src1 = cv.imread("./black.jpg")
cv.imshow("diff1", src1)
src2 = cv.imread("./yellow.jpg")
cv.imshow("diff2", src2)

plt.subplot(1, 2, 1)
plt.title("diff1")
plt.plot(create_gray_hist(src1))
plt.subplot(1, 2, 2)
plt.title("diff2")
plt.plot(create_gray_hist(src2))

hist_compare(src1, src2)
plt.show()
while True:
    k = cv.waitKey(0) & 0xFF
    if k == 27:
        break
cv.destroyAllWindows()

结果如下图所示,这里我找的是两个相似的图片(从找不同游戏里面找到的)。

得到的结果如下:

巴氏距离:0.0501735845451386, 相关性:0.9855477082033252, 卡方:3887.8752812639, 十字交叉:166493.0

由于两张图非常相似,得到的结果也符合刚才的说明。

  • 巴氏距离:0.0501735845451386 >>> 值越小,相关度越高,最大值为 1,最小值为 0;
  • 相关性:0.9855477082033252 >>> 值越大,相关度越高,最大值为 1,最小值为 0;
  • 卡方:3887.8752812639 >>> 值越小,相关度越高,最大值无上界,最小值 0;(不过看起来,这个好像用处不大)
  • 十字交叉:166493.0 >>> 十字交叉,值越大越相似。

切换成不同的两张图片,可以看一下运行结果,首先看灰度直方图。

在看得到的各个值:

巴氏距离:0.28273836677812036, 相关性:0.4615912771396342, 卡方:186501.9955618743, 十字交叉:126877.0

接下来,我们比较一下彩色图的直方图,这部分我也在网上看到了一个算法,但是由于代码实在没看太懂,直接忽略掉了。以下代码转载自网络,建议本阶段,看一下就好,不要钻牛角尖。

代码来源:网络。

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):
            b = image[row, col, 0]
            g = image[row, col, 1]
            r = 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 create_gray_hist(image):
    # 创建一个灰度直方图
    # img = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    hist = cv.calcHist([image], [1], None, [256],  [0, 256])
    return hist

关于上文提及的 巴氏距离卡方 都属于统计学知识,暂时按下不表。

橡皮擦的小节

希望今天的一个小时,你有所收获,我们下篇博客见~

相关阅读


  1. Python 爬虫 100 例教程,超棒的爬虫教程,立即订阅吧
  2. Python 爬虫小课,精彩 9 讲

今天是持续写作的第 66 / 100 天。
如果你有想要交流的想法、技术,欢迎在评论区留言。


如果你想跟博主建立亲密关系,可以关注同名公众号 梦想橡皮擦,近距离接触一个逗趣的互联网高级网虫。
博主 ID:梦想橡皮擦,希望大家点赞评论收藏

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。