• OpenCV官方教程中文版 —— 2D 直方图


    前言

    本节我们会学习如何绘制 2D 直方图,我们会在下一节中使用到它。

    一、介绍

    在前面的部分我们介绍了如何绘制一维直方图,之所以称为一维,是因为我们只考虑了图像的一个特征:灰度值。但是在 2D 直方图中我们就要考虑两个图像特征。对于彩色图像的直方图通常情况下我们需要考虑每个的颜色(Hue)和饱和度(Saturation)。根据这两个特征绘制 2D 直方图。

    OpenCV 的官方文档中包含一个创建彩色直方图的例子。本节就是要和大家一起来学习如何绘制颜色直方图,这会对我们下一节学习直方图投影有所帮助

    二、OpenCV 中的 2D 直方图

    使用函数 cv2.calcHist() 来计算直方图既简单又方便。如果要绘制颜色直方图的话,我们首先需要将图像的颜色空间从 BGR 转换到 HSV。(记住,计算一维直方图,要从 BGR 转换到 HSV)。计算 2D 直方图,函数的参数要做如下修改:

    • channels=[0,1] 因为我们需要同时处理 H 和 S 两个通道。

    • bins=[180,256] H 通道为 180,S 通道为 256。

    • range=[0,180,0,256] H 的取值范围在 0 到 180,S 的取值范围在 0 到 256。

    代码如下:

    # -*- coding: utf-8 -*-
    import cv2
    img = cv2.imread('home.png')
    hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    hist = cv2.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
    
    • 1
    • 2
    • 3
    • 4
    • 5

    三、Numpy 中 2D 直方图

    Numpy 同样提供了绘制 2D 直方图的函数:np.histogram2d()。(还记得吗,绘制 1D 直方图时我们使用的是 np.histogram())。

    # -*- coding: utf-8 -*-
    import cv2
    import numpy as np
    img = cv2.imread('home.png')
    hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    h, s, v = cv2.split(hsv)
    hist, xbins, ybins = np.histogram2d(h.ravel(),s.ravel(),[180,256],[[0,180],[0,256]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    第一个参数是 H 通道,第二个参数是 S 通道,第三个参数是 bins 的数目,第四个参数是数值范围。
    现在我们要看看如何绘制颜色直方图。

    四、绘制 2D 直方图

    方法 1:使用 cv2.imshow() 我们得到结果是一个 180x256 的两维数组。所以我们可以使用函数 cv2.imshow() 来显示它。但是这是一个灰度图,除非我们知道不同颜色 H 通道的值,否则我们根本就不知道那到底代表什么颜色。

    方法 2:使用 Matplotlib() 我们还可以使用函数 matplotlib.pyplot.imshow()来绘制 2D 直方图,再搭配上不同的颜色图(color_map)。这样我们会对每个点所代表的数值大小有一个更直观的认识。但是跟前面的问题一样,你还是不知道那个数代表的颜色到底是什么。虽然如此,我还是更喜欢这个方法,它既简单又好用。

    注意:在使用这个函数时,要记住设置插值参数为 nearest。

    代码如下:

    b, g, r = cv2.split(img)
    img2 = cv2.merge([r,g,b])
    plt.figure()
    plt.subplot(121)
    plt.imshow(img2, interpolation='bicubic')
    plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
    plt.subplot(122)
    hist = cv2.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
    plt.imshow(hist, interpolation='nearest')
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    下面是输入图像和颜色直方图。X 轴显示 S 值,Y 轴显示 H 值。
    在这里插入图片描述
    在直方图中,你可以看到在 H=100,S=100 附近有比较高的值。这部分与天的蓝色相对应。同样另一个峰值在 H=25 和 S=100 附近。这一宫殿的黄色相对应。你可用通过使用图像编辑软件(GIMP)修改图像,然后在绘制直方图看看我说的对不对。

  • 相关阅读:
    day06_面向对象基础
    Django之视图层
    HTML+CSS+JavaScript仿京东购物商城网站 web前端制作服装购物商城 html电商购物网站
    HFS报告:流程智能是应对宏观经济挑战的第一方法
    MediatR
    P1596 [USACO10OCT]Lake Counting S——dfs连通块
    Spring原理学习(五)初始化与销毁
    Java反射
    动态库加载【Linux】
    vue修饰符的用法
  • 原文地址:https://blog.csdn.net/weixin_42207434/article/details/134062943