灰度阈值是啥意思呢?我们慢慢说。
1.灰度图
我们现在有一张彩色图,我们给它用黑白的方式变现,就形成灰度图,如图所示。
图1
那究竟怎么转换的呢?很简单,我们根据如下公式,把BGR三个通道换成一个Gray通道(0~255):
Gray = R*0.299 + G*0.587 + B*0.114
其中,R,G,B分别代表的是R,G,B三个通道的值(0~255)。
用python语句导入灰度图只需要在导入图像时候后面多一个0即可:
img = cv2.imread("linetest.jpg", 0)
2.灰度直方图
灰度直方图很容易理解,就是我们有一张灰度图,如图1那张。这张图是800*858的尺寸的图。也就是说,该图里面有686400个像素点,每一个像素都对应一个值(0~255),然后我们统计一下0~255这些值共有多少个,并画出统计图:
图2
看图2,输入色阶里面从左到右分别对应的是0~255这些数值的数目。我们发现,这里面亮的点不少(接近255),暗的很少(接近0),不亮不暗的占大多数(中间的值)
3.阈值分割
我们选择0~255之间的一个值,比如150,然后小于等于150都给它变成0,大于150的都给他变为255,这样,我们的图里面就只有两个颜色(黑、白)了。分割后的图像为二值图像,如图3所示:
图3
我们可以使用PYTHON代码来执行这个阈值分割:
ret, thresh = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)
该语句表示:将灰度图像img进行二值化处理,灰度小于150的为0,大于的255
ret: 输入的阈值
thresh : 处理好的图片
cv2.THRESH_BINARY:表示根据灰度小于阈值的为0,大于的255。
确定一个最佳阈值,使背景和目标之间的差异最大,能够有效地分离背景和前景。那么怎么找阈值呢,我们引入大津算法。
4大津算法
有个小日子叫大津展之(おおつのぶゆき),他在1979年时候发明了一个针对二值化的确定最佳阈值有效方法。
图4
这个算法是怎么运行的呢,特别简单。
(1)假定我们灰度图是5*5的尺寸的图。也就是说,该图里面有25个像素点,那么我们设定一个N=25
(2)接下来,我们求一下个灰度值的概率。P_i=n_i/N,其中ni为灰度值i的像素个数。例如,灰度值为150的有5个,那么P_150=n_150/N=5/25=1/5=0.2。
(3)然后我们从阈值为0开始,进行阈值分割为{G1,G2}两组,分别为小于0组G1,大于等于0的组G2。(灰度值小于等于1的都为0,大于1的都为255。)就可以得到G1的总概率值w0,G2的总概率值w1:
也可以得到G1、G2的平均值:
整个图像的灰度平均值、方差可以通过如下式子求得:
当我们求完阈值为0的情况的方差之后,我们进行阈值为1,2,3。。。。。一直到254时候的平均值,方差。然后我们选择方差最大情况下的阈值T,作为我们最终的阈值。
上面的公式我们在其它阈值T下遍历时,可以改为:
我们可以使用PYTHON代码来执行这个大津算法,执行的结果如图5所示:
ret2,thresh2= cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
图5
最后奉上全部代码:
# 导入类库
import cv2
import numpy as np
if __name__ == '__main__':
# 读入灰度图片
img1 = cv2.imread("linetest.jpg")
img2 = cv2.imread("linetest.jpg", 0)
# 显示图片
cv2.imshow('orgin1', img1)
cv2.imshow('orgin2', img2)
#阈值分割
ret1, thresh1 = cv2.threshold(img2, 150, 255, cv2.THRESH_BINARY)
#大津算法
ret2, thresh2 = cv2.threshold(img2, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 显示图片
cv2.imshow('orgin3', thresh1)
cv2.imshow('orgin4', thresh2)
# 按任意键退出
cv2.waitKey()
cv2.destroyAllWindows()
以上就是阈值分割的所有内容啦!