直方图基于OpenCV4

这篇博客介绍了如何使用OpenCV4计算图像的灰度直方图和2D直方图。通过cv.calcHist()函数,我们可以获取图像的像素频数,并利用Matplotlib进行直方图的绘制。对于彩色图像,转换为HSV格式后可以进行色调和饱和度的2D直方图分析,进一步丰富了图像的统计描述。
摘要由CSDN通过智能技术生成

直方图基于OpenCV4

图像直方图是图像的重要统计特征,是表示数字图像中的每一灰度级与该灰度级出现的频数(该灰度级的数目)间的统计关系。按照直方图定义可表示为:
P ( r k ) = n k N ( k = 0 , 1 , 2 , ⋯   , L − 1 ) P(r_k)=\frac{n_k}{N} \qquad (k=0,1,2,\cdots ,L-1) P(rk)=Nnk(k=0,1,2,,L1)
式中: N N N为一幅图像的总像素数; n k n_k nk为第 k k k级灰度的像素数; r k r_k rk为第 k k k级灰度级; L L L为灰度级数; P ( r k ) P(r_k) P(rk)为该灰度级出现的概率。
直方图具有以下性质:
(1)直方图是图像的一维信息描述
在直方图中,由于他只能反应图像的灰度范围、灰度级的分布、整幅图像的平均亮度等信息,而未能反应图像某一灰度值像素所在的位置,从而失去了图像的二维特征。
(2)灰度直方图与图像的映射关系并不唯一
该性质可基于性质一,由于直方图不包含空间位置信息,一张灰度直方图可对应多张图像,但一张图像只能对应一张灰度直方图。
在这里插入图片描述
例如,上述两张图象在灰度像素数目相同的情况下,对应同一张灰度直方图。
(3)直方图满足叠加性
如果已知直方图被分割成几个区域后的各个区域的直方图,则把他们加起来就可得到这个图像的直方图。
在这里插入图片描述
我们常常基于opencv进行直方图的计算和绘制。
OpenCV4提供了函数cv.calcHist(),该函数能够统计出图象中的每个像素的个数:

hist=cv.calcHist(images,channels,mask,histSize,ranges,hist,accumulate)
  • images:待统计直方图的图像数组,数组中所有的图像应具有相同的尺寸和数据类型,并且数据类型只能是CV_8U、CV_16U和CV_32F三种中的一种,但是不同图像的通道数可以不同。
  • channels:需要统计的通道索引数组,第一个图像的通道索引从0到images[0].channels()-1,第二个图像通道索引从images[0].channels()到images[0].channels()+ images[1].channels()-1,以此类推。
  • mask:可选的操作掩码,如果是空矩阵则表示图像中所有位置的像素都计入直方图中,如果矩阵不为空,则必须与输入图像尺寸相同且数据类型为CV_8U。
  • hist:输出的统计直方图结果,是一个dims维度的数组。
  • ranges:每个图像通道中灰度值的取值范围
  • accumulate:是否累积统计直方图的标志,如果累积(true),则统计新图像的直方图时之前图像的统计结果不会被清除,该同能主要用于统计多个图像整体的直方图。
    调用该函数后可得到图像中任意灰度级的像素频数,我们可依托Matplotlib库对生成的数列绘制灰度直方图。
import cv2 as cv
import sys
import numpy as np
from matplotlib import pyplot as plt
np.set_printoptions(suppress=True)

if __name__=='__main__':
    #这里读入的三通道的图像,我们计算灰度直方图的时候需要每个通道单独处理
    image=cv.imread('OIP-C.jfif')
    cv.imshow('image',image)

    if image is None:
        print("Failed to read image")
        sys.exit()
    color=('r','g','b')
    for i,col in enumerate(color):
        #这里hist为每个通道的像素频数,如果需要概率值,需要除以每个通道的像素总数
        hist = cv.calcHist([image], [i], None, [256], [0, 256])*3/image.size
        plt.plot(hist,color=col)
    #_,_,_=plt.hist(x=image.ravel(),bins=256,range=[0,256])
    cv.imshow('image',image)
    plt.show()
    cv.waitKey(0)
    cv.destroyAllWindows()


在这里插入图片描述
在这里插入图片描述
对于彩色图像来说,如果仅仅考虑灰度直方图的话不能满足我们的需求,因此我们通常考虑图像的色调和饱和度,并根据则两个特征进行2D直方图统计。
类似于一维直方图计算,2D直方图的计算同样使用函数cv.calcHist()函数,但在计算之前,需要将图像从BGR格式转化为HSV格式,且其中的几个参数需要进行相应的修改。其中,channels表示需要统计H和S两个通道,值为[0,1];histSize为[180,256],其中180代表H通道,256代表S通道;ranges为[0,180,0,256]

import cv2 as cv
import sys
import numpy as np
from matplotlib import pyplot as plt
np.set_printoptions(suppress=True)

if __name__=='__main__':
    #这里读入的三通道的图像,我们计算灰度直方图的时候需要每个通道单独处理
    image=cv.imread('OIP-C.jfif')
    cv.imshow('image',image)
    image_hsv=cv.cvtColor(image,cv.COLOR_BGR2HSV)

    if image is None:
        print("Failed to read image")
        sys.exit()


    #这里hist为每个通道的像素频数,如果需要概率值,需要除以每个通道的像素总数
    hist = cv.calcHist([image_hsv], [0,1], None, [180,256], [0,180,0,256])
    plt.imshow(image_hsv)
    #_,_,_=plt.hist(x=image.ravel(),bins=256,range=[0,256])
    plt.imshow(hist,interpolation='nearest')
    plt.show()
    cv.waitKey(0)
    cv.destroyAllWindows()



生成2D直方图如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值