美文网首页Python_图像处理
Python OpenCV 图像处理之直方图的应用,取经之旅第

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

作者: 梦想橡皮擦 | 来源:发表于2021-11-23 20:23 被阅读0次

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

    基础知识铺垫

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

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

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

    cv2.compareHist 函数

    该函数原型如下:

    cv2.compareHist(H1, H2, method)
    

    参数说明如下:

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

    其中比较方式涉及如下几种枚举值。

    • <kbd>cv2.HISTCMP_CORREL</kbd>:相关性比较,值越大,相关度越高,最大值为 1,最小值为 0;
    • <kbd>cv2.HISTCMP_CHISQR</kbd>:卡方比较,值越小,相关度越高,最大值无上界,最小值 0;
    • <kbd>cv2.HISTCMP_BHATTACHARYYA</kbd>:巴氏距离比较,值越小,相关度越高,最大值为 1,最小值为 0;
    • <kbd>cv2.HISTCMP_INTERSECT</kbd>:十字交叉,值越大越相似。

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

    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()
    

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


    20210127191953928[1].png

    得到的结果如下:

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

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

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

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

    20210127193407582[1].png

    在看得到的各个值:

    巴氏距离: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 讲

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


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

    相关文章

      网友评论

        本文标题:Python OpenCV 图像处理之直方图的应用,取经之旅第

        本文链接:https://www.haomeiwen.com/subject/vuqgtrtx.html