第一课:绘制直方图
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
def plot_demo(image):
plt.hist(image.ravel(),256,[0,256])
plt.show()
def image_hist(image):
color = ('blue','green','red')
for i,color in enumerate(color):
#计算直方图
hist = cv.calcHist(image,[i],None,[256],[0,256])
#画出直方图
plt.plot(hist,color=color)
plt.xlim(0,256)
plt.show()
src = cv.imread("E:/opencv/picture/Greatwall.jpg")
cv.imshow("initial_window",src)
plot_demo(src)
image_hist(src)
cv.waitKey(0)
cv.destroyAllWindows()
效果图:
7-1源图像
7-2 plot_demo
7-3 image_hist
分析:
1. 什么叫直方图?
答:简单来说就是图像中每个像素值的个数统计。比如说一副灰度图中像素值为0的有多少个,像素值为1的有多少个….直方图是一种分析图片的手段。
在计算直方图之前,有几个术语需要先了解一下:
dims:要计算的通道数,对于灰度图dims = 1,对于rgb图像dims= 3
range:要计算的像素值范围,一般为【0,256】(不包括256)
bins:子区间数目,如果我们统计0~255每个像素值,bins =256;如果划分区间,比如【0,15】,【16,31】,….【240,255】这样的16个区间,bins = 16
2. 需要安装matplotlib
pip install matplotlib
3. plot_demo(matplotlib自带的计算并绘制直方图)
def plot_demo(image):
plt.hist(image.ravel(),256,[0,256])
plt.show()
1) image.ravel()函数的功能是将多维数组降为一维数组
2)matplotlib.pyplot.hist函数主要是计算直方图
hist函数原型:hist(x, bins=None, range=None,….)
x参数表示是一个数组或一个序列,是指定每个bin(箱子)分布的数据
bins参数表示指定bin(箱子)的个数,也就是总共有几条条状图
range参数表示箱子的下限和上限。即横坐标显示的范围,范围之外的将被舍弃。
range这个参数一般都是[0,256]
3)plt.show()显示直方图
4. image_hist
def image_hist(image):
#注意这个是tuple()哦,且里面的是字符‘’而不是字符串
color = ('blue','green','red')
for i,color in enumerate(color):
hist =cv.calcHist(image,[i],None,[256],[0,256])
plt.plot(hist,color=color)
plt.xlim(0,256)
plt.show()
1) enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据下标和数据,一般用在 for 循环当中。
语法:
enumerate(sequence, [start=0])
参数:
• sequence -- 一个序列、迭代器或其他支持迭代对象。
• start -- 下标起始位置。
返回值
返回 enumerate(枚举) 对象。
举个例子:
对于普通的for循环:
>>>i = 0
>>> seq = ['one', 'two', 'three']
>>> for element in seq:
print i, seq[i]
i +=1
0 one
1 two
2 three
对于for循环使用enumerate:
>>>seq = ['one', 'two', 'three']
>>> for i, element in enumerate(seq):
print i, element
0 one
1 two
2 three
2)cv2.calcHist的原型为:calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]]) -> hist
images参数表示输入图像,传入时应该用中括号[ ]括起来
channels参数表示传入图像的通道,如果是灰度图像,那就不用说了,只有一个通道,值为0,如果是彩色图像(有3个通道),那么值为0,1,2,中选择一个,对应着BGR各个通道。这个值也得用[ ]传入。
mask参数表示掩膜图像。如果统计整幅图,那么为None。主要是如果要统计部分图的直方图,就得构造相应的掩膜来计算。
histSize参数表示灰度级的个数,需要中括号,比如[256]
ranges参数表示像素值的范围,通常[0,256]。此外,假如channels为[0,1],ranges为[0,256,0,180],则代表0通道范围是0-256,1通道范围0-180。
3)plt.plot与plt.xlim函数
plt.plot(hist,color=color)
plt.xlim(0,256)
plt.plot函数:绘制函数图像
参数一:列表或者数组
参数二:控制颜色参数
plt.xlim函数:设置坐标轴刻度的取值范围
第二课 直方图均衡化与比较
均衡化(全局与部分)
opencv的直方图均衡化都是基于灰度图像的
作用:直方图均衡化可以调整图像的对比度,使图像更加清晰,对比度增强。是图像增强的一个手段。
直方图均衡化:如果一副图像的像素占有很多的灰度级而且分布均匀,那么这样的图像往往有高对比度和多变的灰度色调。直方图均衡化就是一种能仅靠输入图像直方图信息自动达到这种效果的变换函数。它的基本思想是对图像中像素个数多的灰度级进行展宽,而对图像中像素个数少的灰度进行压缩,从而扩展像元取值的动态范围,提高了对比度和灰度色调的变化,使图像更加清晰。
源码:
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
def hist_demo(image):
hist = plt.hist(image.ravel(),256,[0,256])
plt.show()
def Image_hist(image):
color = ("b","g","r")
for i,color in enumerate(color):
#计算直方图
hist = cv.calcHist(image,[i],None,[256],[0,256])
plt.xlim(0,256)
plt.plot(hist,color)
plt.show()
#opencv的直方图均衡化都是基于灰度图像的
#直方图均衡化可以自动的调整图像的对比度,使图像更加清晰化,对比度增强,是图像增强的一个手段
def equalHist_demo(image):
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
cv.imshow("gray",gray)
dst = cv.equalizeHist(gray)
cv.imshow("dst_win1",dst)
#可以明显的看出dst_win1的对比度要比gray的对比度要高好多。
def clahe_demo(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("gray", gray)
clahe = cv.createCLAHE(clipLimit=5.0,tileGridSize=(8,8))
dst = clahe.apply(gray)
cv.imshow("dst_win2", dst)
#之前学习的调节对比度以及锐化图像的方法
def contrast_demo(image,c,gamm):
#blank = np.zeros(image.shape,np.uint8)
#dst = cv.addWeighted(image,c,blank,0,gamm)
kernel = np.array([[0,-1,0],[-1,5,-1],[0,-1,0]])
dst = cv.filter2D(image,-1,kernel)
cv.imshow("dst_win",dst)
src = cv.imread("E:/opencv/picture/lena.jpg")
cv.imshow("inital_win",src)
#hist_demo(src)
#Image_hist(src)
#contrast_demo(src,2,2)
equalHist_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()
得出结果如下:
原图 灰度图
图像全均衡化 自适应直方图均衡化(均衡参数可调推荐)
分析:
1)#opencv的直方图均衡化都是基于灰度图像的
#直方图均衡化可以自动的调整图像的对比度,使图像更加清晰化,对比度增强,是图像增强的一个手段
#全局直方图均衡化
def equalHist_demo(image):
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
cv.imshow("gray",gray)
dst = cv.equalizeHist(gray)
cv.imshow("dst_win1",dst)
#可以明显的看出dst_win1的对比度要比gray的对比度要高好多。
api: cv.equalizeHist(src) 对输入的源灰度图像进行直方图均衡化处理,从而提高图像质量。如果源图像是彩色图像,得需先转化成灰度图像。
2) 自适应(局部)直方图均衡化(可调参数)
.全局直方图均衡化可能得到是一种全局意义上的均衡化,但是有的时候这种操作并不是很好,会把某些不该调整的部分给调整了。Opencv中还有一种直方图均衡化,它是一种局部直方图均衡化,也就是是说把整个图像分成许多小块(比如按10*10作为一个小块),那么对每个小块进行均衡化。
注:全图的直方图均衡化会导致对比度过度增强,所以在一些情况下应使用局部直方图均衡化;
#局部直方图均衡化
def clahe_demo(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("gray", gray)
clahe = cv