图像直方图:
一副灰度图像是由不同的灰度的像素值组成的,而图像中的灰度值的分布则反映了一定的图像特征,即图像亮度特征,如果直方图的值偏向于0,则表示该图像亮度偏暗,如果直方图的值偏向于255(我们通常进行归一化,将图像的像素值设置在[0,1]区间内,则表示该图像亮度偏亮,我们画出的直方图横坐标表示灰度值,纵坐标表示该灰度值出现的次数
下面我们来分析一张图像的直方图:
从上图看出该图的(图像的直方图一定要根据灰度图像绘制,而不是彩色图像),图像的灰度主要分布在两边,也就是黑色区域和白色区域较多,即对应图片中的山和水,而处在中间的灰度像素较少。
那么在opencv中我们该如何得到一副图像的灰度图呢?
Hist = cv2.calcHist(images; channels; mask; histSize; ranges[; hist[; accumulate]])
img:传入的图片(灰度)
channels:如果传入的是灰度图像则为0,否则根据[b],[g],[r]选择1,2,3,
mask:掩模
histSize:直方图分为多少个bin即分为多少个区间[255]
ranges:直方图值得范围[0,255]
注意:这里Hist我们得到的是一个256x1的数组,每一个值代表了与次灰度值对应的像素点数目。不能通过cv.imshow(hist)来显示直方图,那么如何来显示直方图呢?
这里我们可以使用
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image/lufei.jpeg',0)
plt.hist(img.ravel(),255,[0,256]);
plt.title("Matplotlib Method")
plt.show()
来显示一个图像的直方图
同时我们还可以来绘制多个通道的直方图,得到类似下方的图像
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('image/lufei.jpeg')
color = ('b','g','r')
for i,col in enumerate(color):
histr = cv2.calcHist([img], [i], None, [256], [0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.title("Matplotlib color Method")
plt.show()
直方图均衡化:说完了图像的直方图,下面我们就来继续说一下直方图的均衡化,首先我们要理解什么是直方图的均衡化呢,通俗点解释就是,当我们发现一张图片比较暗(如夜间拍的图片)整体会显得暗一些,如果我们画出这张图片的直方图,这个直方图的整体数值就会偏向于0,然而这并不是我们想得到的,我们想要得到的是一个每个像素值的分布处在一个尽量均匀分布的状态,这样我们才能得到清晰的图像,换句话说也就是我们增强图像的对比度
下面我们来看一下直方图均衡化的步骤:
①统计原始图像各灰度级的像素数目nk,k=0,1,…,L-1;
②计算原始图像的直方图,即各灰度级的概率密度pr(rk)=nk/n;
③计算各灰度级的累积概率分布:
④计算最后的输出灰度级:
其中,Int[*]代表取整运算符;
⑤利用rk和sk的映射关系,修改原图的灰度级,获得增强图像,使得图像直方图为近似均匀分布。
故,实质是把src原图像中像素s经过T变换转化后到dst源图像中r;
下面我们来看一个例子来帮助我们来理解
假设有一个图像矩阵
我们根据图像得到以下统计信息
映射后的灰度值为
累计概率*直方图范围的最大值
得到结果之后取整
随后我们得到映射后的图像
好了 今天就到这里了,欢迎大家有什么问题一起交流学习!