opencv之直方图处理

Posted miaorn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv之直方图处理相关的知识,希望对你有一定的参考价值。

直方图是图像处理过程中的一种非常重要的分析工具。  是图像内灰度值的统计特性与灰度值之间的函数,直方图统计图像内各个

灰度级出现的次数

需要注意三个概念:

DIMS : 表示绘制直方图时,收集的参数的数量,一般情况下,直方图中收集的数据只有一种,就是灰度级,因此该值为1

RANGE :表示统计的灰度级的范围,一般为[0 . 255] . 0对应的时黑色,255对应的时白色

BINS : 参数子集的数目,在处理数据的过程中,有时需要将众多的数据划分为若干个组,在进行分析

技术图片

 

 

 该图中,BINS为6,RANGE为[2,6]

 

python 的模块matplotlib.pyplot中的hist()函数能方便的绘制直方图,

函数形式为

matplotlib.pyplot.hist( x , BINS)

x,为数据源 ,必须是一维的,图像通常都是二维的, 可以通过函数ravel()来将二维数组降成一维的

例如:图像x

23 34 14
54 63 23
45 25 76

对其使用函数ravel()

y = x.ravel()

得到y为:

23 34 14 54 63 23 45 25 76

 

BINS为灰度级的分组情况

 

绘制图像的直方图

1 import cv2
2 import matplotlib.pyplot as plt
3 o = cv2.imread("/home/miao/dog.jpg")
4 cv2.imshow("original" , o) 
5 plt.hist(o.ravel()  , 256)
6 cv2.waitKey()
7 cv2.destroyAllWindows()                                                          
8 plt.show()

这里要有函数plt.show()才会显示出直方图

图像

技术图片

 

 

 直方图

技术图片

 

 

 将灰度级划分为16个子集

技术图片

 

 

opencv提供了函数,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值需要用[ ] 括起来

ranges像素值范围, 例如8位灰度图像范围为 [ 0 , 256 ]

accumulate 累计默认值为False , 如果设置为True时, 计算的是多个直方图的累计结果

 

plot()函数绘制图像的直方图

  color = ‘b‘ 表示曲线是蓝色的  color = ‘ g‘  表示曲线为绿色    color = ‘r‘表示曲线为红色

 

1 import cv2                                                                       
2 import matplotlib.pyplot as plt
3 o = cv2.imread("/home/miao/dog.jpg")
4 histb = cv2.calcHist([o] , [0] , None , [256] , [0,255])
5 print(type[histb])
6 print(histb.shape)
7 peitn(histb.size)
8 plt.plot(histb , color = b)
9 plt.show()

 

<class numpy.ndarray>
(256, 1)
256

返回类型为ndarray

数据为256列 1行

有256个元素

技术图片

 

 使用掩模绘制直方图

 

 1 import cv2
 2 import numpy as np                                                               
 3 import matplotlib.pyplot as plt
 4 image = cv2.imread("/home/miao/dog.jpg" , cv2.IMREAD_GRAYSCALE)
 5 mask = np.zeros( image.shape , np.uint8)
 6 mask[100:200 , 50:150] = 255
 7 histImage = cv2.calcHist([image] , [0] , None , [256] , [0,255] )
 8 histMi = cv2.calcHist( [image] , [0] , mask , [256] , [0,255])
 9 plt.plot(histImage)
10 plt.plot(histMi)
11 plt.show()

掩模之前有描述过就不再多说

技术图片

 

 

直方图的均衡化

目地主要是将原始图像的灰度级均匀的映射到整个灰度级范围内,得到一个灰度级均匀的图像

实现方法为,将该灰度级出来的概率累计之前灰度级的概率之和  ,然后乘以最大灰度值,所得即为均衡化图像

 

 1 import cv2                                                                       
 2 import matplotlib.pyplot as plt
 3 img = cv2.imread("/home/miao/dog.jpg" , cv2.IMREAD_GRAYSCALE)
 4 equ = cv2.equalizeHist(img)
 5 cv2.imshow("original" , img)
 6 cv2.imshow("result" , equ)
 7 plt.figure("原始图像直方图")
 8 plt.hist(img.ravel() , 256)
 9 plt.figure("均衡化结果直方图")
10 plt.hist(equ.ravel() , 256)
11 plt.show()
12 cv2.waitKey()
13 cv2.destroyAllWindows()

原图

技术图片

 

 直方图均衡化处理

技术图片

 

 

原始图像直方图

技术图片

 

 均衡化结果直方图

技术图片

 

可以看出原图左侧比较密集整体较高 , 在均衡化处理之后 左侧变得稀疏 ,右侧密集  , 整体来看是比较均衡的

 

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

例如:subplot(2,3,5) 表示在 两行三列的窗口上在第4个位置上,添加一个子窗口 。 窗口的序号是从1开始的

 

1 import cv2
2 import matplotlib.pyplot as plt                                                  
3 img = cv2.imread("/home/miao/dog.jpg" , cv2.IMREAD_GRAYSCALE)
4 equ = cv2.equalizeHist(img)
5 plt.figure("subplot")
6 plt.subplot(121) , plt.hist(img.ravel() , 256)
7 plt.subplot(122) , plt.hist(equ.ravel() , 256)
8 plt.show()

 

技术图片

 

 

 

matplotlib.pyplot.imshow( X , cmap = None )

X为图像信息,可以是各种形式的值

cmap表示色彩空间,默认为None , 默认使用RGB(A)色彩空间

 1 import cv2
 2 import matplotlib.pyplot as plt                                                  
 3 import pylab
 4 img = cv2.imread("/home/miao/dog.jpg")
 5 imgRGB = cv2.cvtColor(img , cv2.COLOR_BGR2RGB)
 6 plt.figure("显示结果")
 7 plt.subplot(121)
 8 plt.imshow(img)  , plt.axis(off)
 9 plt.subplot(122) 
10 plt.imshow(imgRGB) , plt.axis(off)
11 pylab.show()

plt.axis(‘off‘)是关闭坐标轴的显示

技术图片

 

 可以看到左侧直接使用默认参数色彩空间模式显示是不正常的,因为图像读取时时按BGR通道读取的,

而该函数时按RGB通道显示的, 需要通过函数改变通道顺序 则可以正常显示。

 

没有pylab模块是不会显示的,具体原因,还未查找

 

以上是关于opencv之直方图处理的主要内容,如果未能解决你的问题,请参考以下文章

opencv之直方图处理

OpenCV图像处理应用(面向Python)之直方图

OpenCV图像处理应用(面向Python)之直方图

OpenCV图像处理应用(面向Python)之直方图

OpenCV 学习笔记(颜色直方图计算 calcHist)

图像处理OpenCV(C++版)——4.1 对比度增强之灰度直方图