【OpenCV-Python】——绘制/查找图像直方图&全局/自适应直方图均衡化&二维直方图

目录

前言:

1、直方图基础

1.1 用hist()函数绘制直方图

 1.2 用calcHist()函数查找直方图

2、直方图均衡化

2.1 普通直方图均衡化

 2.2 限制对比度自适应直方图均衡化

 3、 二维直方图

3.1 OpenCV中的二维直方图

3.2 Numpy中的二维直方图

总结:


前言:

直方图是一种重要的图像分析工具,它用于描述图像内部的灰度级信息,可直观地反映图像的对比度、亮度、强度分布等特征。

1、直方图基础

直方图用于统计图像内各个灰度级出现的次数,横坐标表示图像像素的灰度级,纵坐标表示像素灰度级的数量。三个概念需要注意:RANGE统计的灰度级范围;BINS灰度级的分组数量(一个灰度子集的数量值);DIMS绘制直方图时采集的参数数量(一般直方图只采集灰度级,DIMS为1)。

1.1 用hist()函数绘制直方图

matplotlib.pyplot.hist()函数查找完直方图可直接绘制,然后调用显示函数查看即可:

matplotlib.pyplot.hist(src,bins)

src是用于绘制直方图的图像数据,必须是一维数组。BGR是三维数组,要用raval()函数转换为一维;bins是灰度级分组数量。

import cv2
import matplotlib.pyplot as plt
img=cv2.imread('boy.png')
cv2.imshow('img',img)
plt.hist(img.ravel(),256)
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()

 1.2 用calcHist()函数查找直方图

 calHist()函数查找完直方图后直接返回的结果是一维数组,要借助绘制函数和显示函数:

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

hist返回的是一维数组,大小是256,保存了各个灰度级的数量;image实际参数需要用【】框起来;channels是通道编号,灰度图像为【0】,BGR图像分别为【0】【1】【2】;mask是掩模图像,为None时统计整个图像;histSize是BINS值,实际参数要用【】框起来;ranges为像素值范围,8位灰度图像是【0,255】。

import cv2
import matplotlib.pyplot as plt
img=cv2.imread('boy.png')
cv2.imshow('img',img)
histB =cv2.calcHist([img],[0],None,[256],[0,255])#整幅图统计B通道
histG =cv2.calcHist([img],[1],None,[256],[0,255])#整幅图统计G通道
histR =cv2.calcHist([img],[2],None,[256],[0,255])#整幅图统计R通道
plt.plot(histB,'b')  #需借助绘制函数绘制
plt.plot(histG,'g')
plt.plot(histR,'r')
plt.show()

     

 应用掩模的直方图:

mask参数指定掩模,掩模图像时黑底,其中间的白色区域时可视化透明区域,将其覆盖到原图像上,原图像可显示出来的部分为掩模结果图像。

import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('boy.png')
cv2.imshow('img',img)
w,h,d=img.shape
mask=np.zeros((w,h),np.uint8)  #按原图大小创建一幅黑色图像
w1=np.int0(w*0.25)    #设置白色透明区域
w2=np.int0(w*0.75)
h1=np.int0(h*0.25)
h2=np.int0(h*0.75)
mask[w1:w2, 100:500]=255      #设置为255白色掩模区域
cv2.imshow('mask',mask)
histB =cv2.calcHist([img],[0],mask,[256],[0,255])#整幅图统计B通道
histG =cv2.calcHist([img],[1],mask,[256],[0,255])#整幅图统计G通道
histR =cv2.calcHist([img],[2],mask,[256],[0,255])#整幅图统计R通道
plt.plot(histB,'b')  #需借助绘制函数绘制
plt.plot(histG,'g')
plt.plot(histR,'r')
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()

  

2、直方图均衡化

直方图均衡化通过调整图像的灰度来提高图像的对比度。

2.1 普通直方图均衡化

主要是指将原图像的灰度级均匀地映射到全部灰度级范围内。利用cv2.equalize()函数:

dst=cv2.equalizeHist(src)

src是原图像,必须为8位的单通道图像。

import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('boy.png',0)  #打开灰度图,注意参数0
cv2.imshow('img',img)        #显示原图像
plt.figure('原图直方图')
plt.hist(img.ravel(),256)    #绘制原直方图
equ=cv2.equalizeHist(img)    #均衡化(后的图像)
cv2.imshow('equ',equ)        #显示均衡后的图像
plt.figure('均衡化后直方图')
plt.hist(equ.ravel(),256)    #绘制均衡化后图像的直方图
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 2.2 限制对比度自适应直方图均衡化

普通直方图均衡化用于对图像全局进行调整,不能有效提高图像的局部对比度。可以把图像分成若干子块,对子块进行直方图均衡化,即自适应直方图均衡化。但是这会导致图像局部对比度过高,导致图像失真,为解决此问题,可对局部对比度进行限制。

cv2.createCLAHE()函数用于创建CLAHE对象:

retval=cv2.creatCLAHE(clipLimit,tileGridSize)

retval是返回的CLAHE对象。两个参数都是可选参数,clipLimit是对比度受限阈值,默认40.0;tileGridSize是直方图均衡化的网格大小,默认(8,8)。调用CLAHE对象的apply()方法,将其应用到图像中进行均衡化。

import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('man.png',0)  #打开单通道灰度图,注意参数0
cv2.imshow('img',img)        #显示原图像
equImg=cv2.equalizeHist(img)    #均衡化(后的图像)
cv2.imshow('equImg',equImg)        #显示普通均衡后的图像
clahe=cv2.createCLAHE(clipLimit=5)  #创建CLAHE对象
claheImg=clahe.apply(img)   #应用CLAHE对象
cv2.imshow('claheImg',claheImg)  #显示自适应均衡化后的图像
cv2.waitKey(0)
cv2.destroyAllWindows()

 3、 二维直方图

 前面介绍的直方图只统计像素的灰度值这一个特征,属于一维直方图。下面介绍二维直方图统计像素的色相和饱和度,用于查找图像的颜色直方图。

3.1 OpenCV中的二维直方图

仍使用cv2.calcHist()函数,只是指定参数时与之前有所区别:image应该从BGR色彩空间转换位HSV色彩空间,实际参数需用【】框起来;channels设置为【0,1】时表示同时处理色相和饱和度;histSize设置BINS值为【180,256】时,表示色相为180,饱和度为256;ranges设置为【0,180,0,256】时表示色相取值范围是【0,180】,饱和度的取值范围是【0,256】。且此处cv2.calcHist()函数返回的颜色直方图不用借助plot绘制函数了,直接用cv2.imshow()函数显示即可

import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('man.png')  #打开原图像
cv2.imshow('img',img)        #显示原图像
img2=cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #转换色彩空间为HSV
hist=cv2.calcHist([img2],[0,1],None,[180,256],[0,180,0,256])  #计算颜色直方图
cv2.imshow('2Dhist',hist)  #显示颜色直方图
cv2.waitKey(0)
cv2.destroyAllWindows()

代码结果如下左图和中间灰度图:

 但是cv2.calcHist()函数返回的颜色直方图是一个大小为180x256的二维数组,cv2.imshow显示时是一幅灰度图像,不能直接显示出颜色的分布情况。

可用plt.imshow()函数绘制具有不同颜色的直方图:(代码结构如上图右边紫色图)

plt.imshow(hist,interpolation='nearest')  #绘制颜色直方图
plt.show()   #显示颜色直方图

3.2 Numpy中的二维直方图

Numpy中的histogram2D()函数用于计算二维直方图,其基本格式如下:

hist,xedges,yedges=np.histogram2D(x,y,bins,range)

hist是返回的直方图,xedges是返回的x的直方图的BINS边界值,yedge同理。x,y是原图对应通道转换成的一维数组(如h.ravel(),s.ravel()这样,ravel用于转换为一维数组);bins为BINS值如【180,256】;range是像素值范围,格式是【【0,180】,【0,256】】。

import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('man.png')  #打开原图像
cv2.imshow('img',img)        #显示原图像
img2=cv2.cvtColor(img, cv2.COLOR_BGR2HSV) #转换色彩空间为HSV
h,s,v=cv2.split(img2)  #h,s通道即对应histogram2d前两个参数的x,y
hist,x,y=np.histogram2d(h.ravel(),s.ravel(),[180,256],[[0,180],[0,256]])  #计算颜色直方图
cv2.imshow('2Dhist',hist)  #直接显示二维直方图(灰度)
plt.imshow(hist,interpolation='nearest')  #绘制颜色直方图
plt.show()   #显示颜色直方图
cv2.waitKey(0)
cv2.destroyAllWindows()

 结果与上面的三个图像相同!

总结:

由于是初学者可能很多地方没有总结完全或者有误,后续深入学习后会不断回来该删,也欢迎各位朋友指正!下次学习模板匹配和图像分割

猜你喜欢

转载自blog.csdn.net/weixin_51658186/article/details/130394716