OpenCV学习笔记(九)——直方图处理

发布时间:2023-07-25 18:30

直方图是图像处理过程中的一种非常重要的分析工具。直方图从图像内部灰度级的角度对图像进行表述,包含十分丰富而重要的信息。从直方图的角度对图像进行处理,可以达到增强图像显示效果的目的。

《OpenCV轻松入门:面向Python》学习笔记(九)

      • 1. 直方图的含义
      • 2. 绘制直方图
        • 2.1 用cv2.calcHist()函数统计图像直方图信息
        • 2.2 plot()函数的使用
        • 2.3 绘制统计直方图
        • 2.4 使用掩模绘制直方图
      • 3. 直方图均衡化
      • 4. pyplot 模块介绍
        • 4.1 subplot函数
        • 4.2 imshow函数

1. 直方图的含义

从统计的角度讲,直方图是图像内灰度值的统计特性与图像灰度值之间的函数,直方图统计图像内各个灰度级出现的次数。从直方图的图形上观察,横坐标是图像中各像素点的灰度级,纵坐标是具有该灰度级(像素值)的像素个数。

\"OpenCV学习笔记(九)——直方图处理_第1张图片\"
在 OpenCV 的官网上,特别提出了要注意三个概念:DIMS、BINS、RANGE。

  • DIMS:表示在绘制直方图时,收集的参数的数量。一般情况下,直方图中收集的数据只有一种,就是灰度级。因此,该值为1。
  • RANGE:表示要统计的灰度级范围,一般为[0, 255]。0 对应的是黑色,255 对应的是白色。
  • BINS:参数子集的数目。在处理数据的过程中,有时需要将众多的数据划分为若干个组,再进行分析。

例如,在灰度图像中,将[0, 255]区间内的256个灰度级,按照每16 个像素一组划分为子集:
[0, 255] = [0, 15] ∪ [16, 31] ∪…∪[240, 255]

按照上述方式,整个灰度级范围可以划分为16 个子集,具体为:整个灰度级范围= bin1 ∪ bin2 ∪…∪ bin16

子集划分完以后,某灰度图像生成的直方图如图所示(图中的b1 代表bin1,b2 代表bin2,以此类推)
\"OpenCV学习笔记(九)——直方图处理_第2张图片\"

2. 绘制直方图

2.1 用cv2.calcHist()函数统计图像直方图信息

hist = cv2.calcHist( images, channels, mask, histSize, ranges, accumulate )

  • hist:返回的统计直方图,是一个一维数组,数组内的元素是各个灰度级的像素个数。
  • images:原始图像,该图像需要使用“[ ]”括起来
  • channels:指定通道编号。通道编号需要用“[ ]”括起来,如果输入图像是单通道灰度图像,该参数的值就是[0]。对于彩色图像,它的值可以是[0]、[1]、[2],分别对应通道B、G、R。
  • mask:掩模图像。当统计整幅图像的直方图时,将这个值设为None。当统计图像某一部分的直方图时,需要用到掩模图像。
  • histSize:BINS 的值,该值需要用“[ ]”括起来。例如,BINS 的值是256,需要使用“[256]”
    作为此参数值。
  • ranges:即像素值范围。例如,8位灰度图像的像素值范围是[0, 255]。
  • accumulate:累计(累积、叠加)标识,默认值为False。如果被设置为True,则直方图在开始计算时不会被清零,计算的是多个直方图的累积结果,用于对一组图像计算直方图。该参数允许从多个对象中计算单个直方图,或者实时更新直方图。该参数是可选的,一般情况下不需要设置

2.2 plot()函数的使用

使用 matplotlib.pyplot 模块内的plot()函数,可以将函数cv2.calcHist()的返回值绘制为图像直方图。下面通过三个例子来学习plot()函数的基本使用方法。

#将给定的x= [0,1,2,3,4,5,6],y = [0.3,0.4,2,5,3,4.5,4],使用plot()函数绘制出来。
import matplotlib.pyplot as plt
x = [0,1,2,3,4,5,6]
y = [0.3,0.4,2,5,3,4.5,4]
plt.plot(x,y)

\"OpenCV学习笔记(九)——直方图处理_第3张图片\"

#给定y = [0.3, 0.4, 2, 5, 3, 4.5, 4],使用plot()函数将其绘制出来,观察绘制结果。
import matplotlib.pyplot as plt
y = [0.3,0.4,2,5,3,4.5,4]
plt.plot(y)

\"OpenCV学习笔记(九)——直方图处理_第4张图片\"

#使用plot()函数将两组不同的值a= [0.3, 0.4, 2, 5, 3, 4.5, 4],b=[3, 5, 1, 2, 1, 5, 3]以不同的颜色绘制出来。
import matplotlib.pyplot as plt
a = [0.3,0.4,2,5,3,4.5,4]
b=[3,5,1,2,1,5,3]
plt.plot(a,color=\'r\')
plt.plot(b,color=\'g\')

\"OpenCV学习笔记(九)——直方图处理_第5张图片\"

2.3 绘制统计直方图

#使用函数plot()将函数cv2.calcHist()的返回值绘制为直方图。
import cv2
import matplotlib.pyplot as plt
o=cv2.imread(\"image\\\\boatGray.bmp\")
histb = cv2.calcHist([o],[0],None,[256],[0,255])
plt.plot(histb,color=\'b\')
plt.show()

\"OpenCV学习笔记(九)——直方图处理_第6张图片\"

#使用函数plot()和函数cv2.calcHist(),将彩色图像各个通道的直方图绘制在一个窗口内。
import cv2
import matplotlib.pyplot as plt
o=cv2.imread(\"image\\\\girl.bmp\")
histb = cv2.calcHist([o],[0],None,[256],[0,255])
histg = cv2.calcHist([o],[1],None,[256],[0,255])
histr = cv2.calcHist([o],[2],None,[256],[0,255])
plt.plot(histb,color=\'b\')
plt.plot(histg,color=\'g\')
plt.plot(histr,color=\'r\')
plt.show()

\"OpenCV学习笔记(九)——直方图处理_第7张图片\"

2.4 使用掩模绘制直方图

左图是原始图像O,中间的是掩模图像M,右图是使用掩模图像M 对原始图像O 进行掩模运算的结果图像R:
\"OpenCV学习笔记(九)——直方图处理_第8张图片\"

import cv2
import numpy as np
import matplotlib.pyplot as plt
image=cv2.imread(\"image\\\\girl.bmp\",cv2.IMREAD_GRAYSCALE)
mask=np.zeros(image.shape,np.uint8)
mask[200:400,200:400]=255
image2=cv2.bitwise_and(image,mask)
histImage=cv2.calcHist([image],[0],None,[256],[0,255])
histMI=cv2.calcHist([image],[0],mask,[256],[0,255])
plt.plot(histImage)
plt.plot(histMI)
cv2.imshow(\"origin\",image)
cv2.imshow(\"after\",image2)
cv2.waitKey()
cv2.destroyAllwindows()

\"OpenCV学习笔记(九)——直方图处理_第9张图片\"

\"OpenCV学习笔记(九)——直方图处理_第10张图片\"

3. 直方图均衡化

如果一幅图像拥有全部可能的灰度级,并且像素值的灰度均匀分布,那么这幅图像就具有高对比度和多变的灰度色调,灰度级丰富且覆盖范围较大。在外观上,这样的图像具有更丰富的色彩,不会过暗或过亮。
\"OpenCV学习笔记(九)——直方图处理_第11张图片\"

dst = cv2.equalizeHist( src )

#-----------导入使用的模块---------------
import cv2
import matplotlib.pyplot as plt
#-----------读取原始图像---------------
img = cv2.imread(\'image\\\\equ.bmp\',cv2.IMREAD_GRAYSCALE)
#-----------直方图均衡化处理---------------
equ = cv2.equalizeHist(img)
#-----------显示均衡化前后的图像---------------
cv2.imshow(\"original\",img)
cv2.imshow(\"result\",equ)
#-----------显示均衡化前后的直方图---------------
plt.figure(\"原始图像直方图\") #构建窗口
plt.hist(img.ravel(),256)
plt.figure(\"均衡化结果直方图\") #构建新窗口
plt.hist(equ.ravel(),256)
#----------等待释放窗口---------------------
cv2.waitKey()
cv2.destroyAllWindows()

\"OpenCV学习笔记(九)——直方图处理_第12张图片\"
直方图均衡化使图像色彩更均衡、外观更清晰,也使图像更便于处理,它被广泛地应用在医学图像处理、车牌识别、人脸识别等领域。

4. pyplot 模块介绍

matplotlib.pyplot模块提供了一个类似于MATLAB绘图方式的框架,可以使用其中的函数方便地绘制图形。

4.1 subplot函数

模块 matplotlib.pyplot 提供了函数matplotlib.pyplot.subplot()用来向当前窗口内添加一个子窗口对象。该函数的语法格式为:

matplotlib.pyplot.subplot(nrows, ncols, index)

  • nrows 为行数。
  • ncols 为列数。
  • index 为窗口序号。

例如,subplot(2, 3, 4)表示在当前的两行三列的窗口的第4 个位置上,添加1 个子窗口:
\"OpenCV学习笔记(九)——直方图处理_第13张图片\"
需要注意的是,窗口是按照行方向排序的,而且序号是从“1”开始而不是从“0”开始的。如果所有参数都小于10,可以省略彼此之间的逗号,直接写三个数字。例如,上述subplot(2, 3, 4)可以直接表示为subplot(234)。

4.2 imshow函数

模块matplotlib.pyplot 提供了函数matplotlib.pyplot.imshow()用来显示图像。其语法格式为:
matplotlib.pyplot.imshow(X, cmap=None)

  • X 为图像信息,可以是各种形式的数值。
  • cmap 表示色彩空间。该值是可选项,默认值为null,默认使用RGB(A)色彩空间
#使用函数matplotlib.pyplot.imshow()显示彩色图像。
import cv2
import matplotlib.pyplot as plt
img = cv2.imread(\'image\\\\girl.bmp\')
imgRGB=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.figure(\"显示结果\")
plt.subplot(121)
plt.imshow(img),plt.axis(\'off\')
plt.subplot(122)
plt.imshow(imgRGB),plt.axis(\'off\')

\"OpenCV学习笔记(九)——直方图处理_第14张图片\"
左图是直接使用默认色彩空间参数模式显示的彩色图像的结果,图像没有正常显示出来。这是因为通过函数cv2.imread()读取的图像,其通道顺序是BGR模式的。而函数matplotlib.pyplot.imshow()的显示顺序是RGB模式的,所以显示出来的图像通道顺序是错乱的,因而无法正常显示。

#使用函数matplotlib.pyplot.imshow()显示灰度图像。
import cv2
import matplotlib.pyplot as plt
o = cv2.imread(\'image\\\\girl.bmp\')
g=cv2.cvtColor(o, cv2.COLOR_BGR2GRAY)
plt.figure(\"灰度图像显示演示\")
plt.subplot(221)
plt.imshow(o),plt.axis(\'off\')
plt.subplot(222)
plt.imshow(o,cmap=plt.cm.gray),plt.axis(\'off\')
plt.subplot(223)
plt.imshow(g),plt.axis(\'off\')
plt.subplot(224)
plt.imshow(g,cmap=plt.cm.gray),plt.axis(\'off\')

\"OpenCV学习笔记(九)——直方图处理_第15张图片\"
只有使用灰度图像作为参数, 并且将色彩空间参数值设置为“cmap=plt.cm.gray”,灰度图像才被正常显示。

#使用函数matplotlib.pyplot.imshow()以不同的参数形式显示灰度图像。
import cv2
import matplotlib.pyplot as plt
o = cv2.imread(\'image\\\\8.bmp\')
g=cv2.cvtColor(o, cv2.COLOR_BGR2GRAY)
plt.figure(\"灰度图像显示演示\")
plt.subplot(221); plt.imshow(g, cmap=plt.cm.gray)
plt.subplot(222); plt.imshow(g, cmap=plt.cm.gray_r)
plt.subplot(223); plt.imshow(g, cmap=\'gray\')
plt.subplot(224); plt.imshow(g, cmap=\'gray_r\')

上述代码中,色彩空间参数cmap 的参数值“plt.cm.gray_r”及“gray_r”中的“r”是英文“reverse”的缩写,表示逆转的意思。
\"OpenCV学习笔记(九)——直方图处理_第16张图片\"

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号