直方图
直方图Histogram是一个基于灰度值的像素分布函数丢失了所有的空间信息。横轴是灰度值纵轴是每个灰度值对应的像素个数。
通过如下代码可以得到一张图像的直方图
import cv2import numpy as npimport matplotlib.pyplot as pltdef plot(grayHist):plt.plot(range(256), grayHist, r, linewidth1.5, cred)y_maxValue np.max(grayHist)plt.axis([0, 255, 0, y_maxValue]) # x和y的范围plt.xlabel("gray Level")plt.ylabel("Number Of Pixels")plt.show()if __name__ "__main__":# 读取图像并转换为灰度图img cv2.imread(rE:dog.jpg, 0)# 图像的高、宽h, w img.shape# 图像的灰度级范围是0~255grayHist np.zeros([256], np.uint64)# 统计每个灰度级的像素个数for i in range(h):for j in range(w):grayHist[img[i][j]] 1# 绘制直方图plot(grayHist)
结果图如下可以看到左图中灰度值为100左右的像素个数最多。
根据直方图的横轴对整个直方图做积分就得到图像的像素总数。
直方图可以帮助分析图像中的灰度变化进而帮助确定最优二值化的灰度阈值threshold level。如果物体与背景的灰度值对比明显此时灰度直方图就会包含双峰bimodal histogram即直方图中一般会有两个峰值分别为图像的前景和背景。
前景使得某个灰度区间的灰度值的数量急剧增加就会产生一个峰值同理背景会使另一个灰度区间的灰度值的数量急剧增加就产生另外一个峰值两峰间的谷底对应于物体边缘附近相对较少数目的像素点。
这两个峰值之间的最小值一般就是最优二值化的分界点通过这个分界点可以把前景和背景很好地分割开来。
有时这两个峰值会有部分重叠即左侧峰值的下降部分和右侧峰值的上升部分存在叠加。通常可以把自然界的信号看做高斯信号即一个峰值对应一个高斯信号当直方图中的两个高斯信号在某个灰度区域叠加的时候其叠加区就形成了一个圆滑的谷底就很难找到一个确切的位置最优二值化的灰度值把这两个峰值分开。
二值化
二值化binarisation一般是指灰度二值化是一种基于灰度直方图的图像分割算法将图像中的像素分为两类最终产生一个二值化的图像。适用于物体与背景的灰度值差别比较大的情况。
二值化算法的初始值被设置为整个图像灰度值的平均值求取最优二值化的值是这个算法的关键也就是尽量求取灰度直方图中两个双峰间的最低点。二值化算法分为两种固定阈值和自适应阈值。
固定阈值二值化
在整个图像中将灰度阈值设置为一个常数将图像中每个像素的灰度值与该阈值相比较从而对整个图像进行分割处理。
如果背景的灰度值在整个图像中可合理地看作为恒定而且所有物体与背景都具有几乎相同的对比度那么只要选择了正确的阈值使用一个固定的全局阈值一般会有较好的效果。
用公式来表示全局阈值
其中 f(x,y) 是原始图像g(x,y) 是二值图像T 是灰度阈值。灰度值小于 T 的像素都设为0反之都设为1。
自适应阈值二值化
图像背景的灰度值可能过于复杂物体和背景的对比度在图像中也有变化一个在图像中某一区域效果良好的阈值在其它区域却可能效果很差。
用一个二值化的值不能很好地对图像进行分类可以将图像划分多个子图像局域对每个子图像单独设置一个二值化的值分别做二值化处理然后将这些子图像进行拼接实现更加优化的分割。
OTSU算法
OTSUs 阈值算法又称大津算法、最大类间方差法该算法是在灰度直方图的基础上用最小二乘法原理推导出来的是具有统计意义上的最佳分割阈值。核心思想就是使类间方差最大要求被分割的物体颜色纹理比较紧凑类内方差小对于一些文本图像的处理比如车牌、指纹效果很好。
基本原理是以最佳阈值将图像的灰度直方图分割成两部分使两部分之间的方差取得最大值即分离性最大。
OTSUs 算法推导
设 X 是一幅具有 L 级灰度的图像其中 i 是像素灰度等级
是该灰度等级的像素个数i 的值在 0 到 L-1 之间。图像的总像素点个数为
第 i 灰度等级的像素在图像中出现的概率为
图像的平均灰度级为
以阈值 k 将所有的像素分为目标和背景两类。其中
类的像素灰度级为 0 到 k-1 类的像素灰度级为 k 到 L-1。 类像素所占面积的比例为 类像素所占面积的比例为 类像素的平均灰度为 类像素的平均灰度为其中
则类间方差公式为
这个方程把前景的信息和背景的信息结合在一起然后令 k 从 0 到 L-1 变化对图像的所有灰度等级的值进行计算计算在不同 k 值下的类间方差使得类间方差最大时的那个 k 值就是所要求的最优二值化阈值。
我们需要求取灰度直方图中两个双峰间的最低点但不是所有的图像都一定存在双峰或者双峰并不明显或者存在多峰这个时候就用 OTSUs 算法来求取最优阈值可能效果不是很好。
参考
PythonOpenCV教程番外篇4Otsu阈值法www.jianshu.com如果觉得有用点个赞吧(ง •̀_•́)ง。
【感谢龙石为本站提供数据采集系统 http://www.longshidata.com/pages/government.html 】