这篇文章主要记录灰度直方图以及常用的几个图像分割方法。
灰度直方图
灰度直方图代表了一幅灰度图像所有像素点在各个灰度值上出现的频率。
一般图像分割是为了把图像主体和背景进行分割从而得到图像主体(或者叫前景)。前景和背景灰度不同,因此在灰度直方图上会形成不同的波峰,找到合适的阈值分割两个波峰即可实现图像分割。
因此灰度直方图给我们的指导作用在于,通过直方图我们可以大概确定阈值应该在什么范围内。
大津阈值化分割
大津分割算法的核心在于自动找到一个合适的阈值。该阈值将把图像所有的像素分为2类,并且能够使类间方差最大。
求取该阈值的方法采用的是遍历法,从1到254,总共254种情况,依次试一遍,即可得到合适的阈值。
opencv中用到的是threshold函数,函数原型如下:
threshold (src, thresh, maxval, type)
参数说明:
src:源图像
thresh:阈值,根据type的值,有时需人工给定
maxval:根据type的值,像素值和阈值进行比较,满足一定条件将把该像素值赋值为maxval
type:
cv2.THRESH_BINARY:将大于阈值的灰度值设为maxval,小于阈值的值设为0
cv2.THRESH_BINARY_INV:将大于阈值的灰度值设为0,其他值设为maxval
cv2.THRESH_TRUNC:将大于阈值的灰度值设为阈值,小于阈值的值保持不变
cv2.THRESH_TOZERO:将小于阈值的灰度值设为0,大于阈值的值保持不变
cv2.THRESH_TOZERO_INV:将大于阈值的灰度值设为0,小于阈值的值保持不变
cv2.THRESH_OTSU:大津阈值化方法,此时thresh自动寻找,传入的参数随意
返回值有两个,第一个是阈值,第二个是二值化后的图像
大津算法的调用方法
_, pic2_thresh = cv.threshold(pic2_gray, 0, 255, cv.THRESH_OTSU)
自适应阈值化分割
和大津算法在全图寻找阈值不同,自适应阈值化分割将图像划分为若干给定尺寸的小邻域,在每个邻域内分别找阈值。
dst = cv.adaptiveThreshold( src, maxValue, adaptiveMethod, thresholdType,blockSize, C[,dst] )
参数说明:
src:源图像
maxValue:同threshold函数
adaptiveMethod:采用的阈值计算方法,取值为ADAPTIVE_THRESH_MEAN_C 和 ADAPTIVE_THRESH_GAUSSIAN_C 。
ADAPTIVE_THRESH_MEAN_C的计算方法是计算出领域的平均值再减去第七个参数double C的值
ADAPTIVE_THRESH_GAUSSIAN_C的计算方法是计算出领域的高斯均值再减去第七个参数double C的值
thresholdType:只有cv2.THRESH_BINARY和cv2.THRESH_BINARY_INV两个取值
blockSize:邻域大小
C:偏移量
这个方法的好处在于能够适应图像不同部分对阈值的需求。
对于上图,硬币的亮度是不同的,若采用全局阈值则必然不能够全部分割成功,而局部阈值可以获得比较好的效果。
实际在使用的时候,大津和自适应阈值分割两种方法各有适用的范围,比如下图的米粒图像,自适应阈值效果就不如大津。
可以看出,采用自适应阈值的效果反而很差。因此两种方法都有适应的范围。