thresholding (阈值转换)
名词,中文翻译为: 阈值转换法;阈值。
image thresholding,这个词看起来比较抽象,但是结合使用场景,就非常好理解了。
其用在, 将灰度图转换为二值图。
- 二值图像是指仅仅包含黑色和白色两种颜色的图像。这种格式下,可以把一张图片理解为只包含 0 或 1 (255) 值的二维矩阵。
- 灰度图 (grayscale image) 将灰度处理为256个灰度级。而不是简单的 0 或 255 两个值。
而有了二值图,就可以方便的进行自动绘制轮廓。所以,图片阈值转换操作非常有价值。
image thresholding 的三种方法
- simple thresholding
- adaptive thresholding
- Otsu's thresholding
simple thresholding (简单阈值转换)
这个方法简单粗暴。对于灰度图像的每个像素:
- 大于阈值的,赋值成一个指定的值,通常是 255
- 小于等于阈值的,赋值为 0
对于的 opencv python 函数:
threshold(src, thresh, maxval, type) -> retval, dst
参数说明:
- src:原图。一般是灰度图
- thresh: 阈值
- maxval:目标值,例如 255
- type: THRESH_BINARY, THRESH_BINARY_INV, THRESH_OTSU 等,其他参考下面的函数说明。
详细参考 threshold 函数说明
Otsu's thresholding (大津阈值转换)
也称为大津算法,大津二值化法,最大类间差法。由日本人大津 Otsu 于 1979 年提出,由此得名。
对于图像识别功能来说,需要手动设置一个阈值其实是不够的,如果能自动确定这个阈值就完美了。 opencv 内置了两个方法来自动选取阈值: Otsu's 及 Triangle。
至于原理,可以参考 大津算法
算法假定该图像根据双模直方图(前景像素和背景像素)把包含两类像素,于是它要计算能将两类分开的最佳阈值,使得它们的类内方差最小;由于两两平方距离恒定,所以即它们的类间方差最大。
我只领会了意思,但没有看懂实现。。。
大津算法使用方法:
ret, th = cv.threshold(img, 0, 255, cv.THRESH_OTSU)
- 参数 thresh 可以为任意值,因为已经不起作用
- 返回值 ret 为最终使用的阈值
adaptive thresholding (自适应阈值转换)
前面的 simple thresholding 和 otsu thresholding 都是在整个图像中使用固定的阈值进行二值化。 但如果图片的不同区域光照条件差异巨大,这个方法就不合适了。所以出现了 adaptive thresholding。
即,不同区域使用不同的阈值。
adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C) -> dst
- adaptiveMethod decides how the threshold value is calculated: cv.ADAPTIVE_THRESH_MEAN_C 均值: The threshold value is the mean of the neighbourhood area minus the constant C. cv.ADAPTIVE_THRESH_GAUSSIAN_C 高斯: The threshold value is a gaussian-weighted sum of the neighbourhood values minus the constant C.
- blockSize: Size of a pixel neighborhood that is used to calculate a threshold value for the pixel: 3, 5, 7, and so on. 必须为奇数?
- C: Constant subtracted from the mean or weighted mean (see the details below). Normally, it is positive but may be zero or negative as well.
- thresholdType: 只能设置成 THRESH_BINARY 或 THRESH_BINARY_INV。不能设置成大津算法。
关键是确定 blockSize 和 C 的值。
同一张图,adaptiveMethod 不同,效果差异巨大。例如:
用 ADAPTIVE_THRESH_GAUSSIAN_C 处理的效果
用 ADAPTIVE_THRESH_MEAN_C 处理的效果
看起来,高斯处理的结果更像轮廓;而均值处理的效果更适合背景分离。
- cv2.ADAPTIVE_THRESH_MEAN_C:邻域所有像素点的权重值是一致的。
- cv2.ADAPTIVE_THRESH_GAUSSIAN_C:与邻域各个像素点到中心点的距离有关,通过高斯方程得到各个点的权重值。参考下面的高斯加权。
自适应阈值法,整个背景被判定为黑的原理
一开始我没有想明白的是,这个阈值是怎么算出来的,那些背景的黑色区域是如何判定出来的? 但是早上上班的路上,走路的时候突然想明白了。看来笨一点没关系,多琢磨琢磨就行了。
使用均值法,假设局部区域 100个像素点,只要有一个是亮点,所有像素点的均值就是一个大于其他99个像素点的值。如此,二值化之后,就会变成黑黑的一片。
非背景区域同理。
如果效果不明显,调整常数 C 即可。
高斯加权
首先要知道什么是高斯分布(英语:Gaussian distribution),即正态分布(英语:Normal distribution),是一个非常常见的连续概率分布。正态分布的概率密度函数曲线呈钟形,因此人们又经常称之为钟形曲线。正态分布是一种钟形曲线,越接近中心,取值越大,越远离中心,取值越小。
正态分布概念是由法国数学家棣莫弗于1733年首次提出的,后由德国数学家Gauss率先将其应用于天文学研究,故正态分布又叫高斯分布。德国10马克的印有高斯头像的钞票,其上还印有正态分布的密度曲线。
例如,用于高斯模糊。因为图像都是连续的,越靠近的点关系越密切,越远离的点关系越疏远。因此,加权平均更合理,距离越近的点权重越大,距离越远的点权重越小。计算平均值的时候,我们只需要将”中心点”作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。
image histogram (图片直方图)
以灰度图为例,我们用横轴代表 0-255 的灰度数值,竖轴代表照片中对应灰度的像素数量,这个函数图像就被称为直方图。 可以借此直观地看到灰度的分布及比例。
而大津算法就是基于直方图计算出来的。举一个极端的例子,一个只有两个灰度值的图片,其直方图只会有两个波峰。 那么其阈值应该是介于两个波峰之间的一个值。
延伸阅读,直方图在摄影中的应用
效果体验
做了一个在线版的 opencv 图像处理微信小程序,欢迎体验
参考
- Image Thresholding (opencv 官方文档)
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式