OpenCV 图像阈值转换,灰度图变为二值图

发布时间: 2022-02-13 23:33:44 作者: 大象笔记

thresholding (阈值转换)

名词,中文翻译为: 阈值转换法;阈值。

image thresholding,这个词看起来比较抽象,但是结合使用场景,就非常好理解了。

其用在, 将灰度图转换为二值图。

而有了二值图,就可以方便的进行自动绘制轮廓。所以,图片阈值转换操作非常有价值。

image thresholding 的三种方法

simple thresholding (简单阈值转换)

这个方法简单粗暴。对于灰度图像的每个像素:

对于的 opencv python 函数:

threshold(src, thresh, maxval, type) ->	retval, dst

参数说明:

详细参考 threshold 函数说明

Otsu's thresholding (大津阈值转换)

也称为大津算法,大津二值化法,最大类间差法。由日本人大津 Otsu 于 1979 年提出,由此得名。

对于图像识别功能来说,需要手动设置一个阈值其实是不够的,如果能自动确定这个阈值就完美了。 opencv 内置了两个方法来自动选取阈值: Otsu's 及 Triangle。

至于原理,可以参考 大津算法

算法假定该图像根据双模直方图(前景像素和背景像素)把包含两类像素,于是它要计算能将两类分开的最佳阈值,使得它们的类内方差最小;由于两两平方距离恒定,所以即它们的类间方差最大。

我只领会了意思,但没有看懂实现。。。

大津算法使用方法:

ret, th = cv.threshold(img, 0, 255, cv.THRESH_OTSU)

adaptive thresholding (自适应阈值转换)

前面的 simple thresholding 和 otsu thresholding 都是在整个图像中使用固定的阈值进行二值化。 但如果图片的不同区域光照条件差异巨大,这个方法就不合适了。所以出现了 adaptive thresholding。

即,不同区域使用不同的阈值。

adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C) ->	dst

关键是确定 blockSize 和 C 的值。

同一张图,adaptiveMethod 不同,效果差异巨大。例如:

用 ADAPTIVE_THRESH_GAUSSIAN_C 处理的效果

用 ADAPTIVE_THRESH_MEAN_C 处理的效果

看起来,高斯处理的结果更像轮廓;而均值处理的效果更适合背景分离。

自适应阈值法,整个背景被判定为黑的原理

一开始我没有想明白的是,这个阈值是怎么算出来的,那些背景的黑色区域是如何判定出来的? 但是早上上班的路上,走路的时候突然想明白了。看来笨一点没关系,多琢磨琢磨就行了。

使用均值法,假设局部区域 100个像素点,只要有一个是亮点,所有像素点的均值就是一个大于其他99个像素点的值。如此,二值化之后,就会变成黑黑的一片。

非背景区域同理。

如果效果不明显,调整常数 C 即可。

高斯加权

首先要知道什么是高斯分布(英语:Gaussian distribution),即正态分布(英语:Normal distribution),是一个非常常见的连续概率分布。正态分布的概率密度函数曲线呈钟形,因此人们又经常称之为钟形曲线。正态分布是一种钟形曲线,越接近中心,取值越大,越远离中心,取值越小。

正态分布概念是由法国数学家棣莫弗于1733年首次提出的,后由德国数学家Gauss率先将其应用于天文学研究,故正态分布又叫高斯分布。德国10马克的印有高斯头像的钞票,其上还印有正态分布的密度曲线。

例如,用于高斯模糊。因为图像都是连续的,越靠近的点关系越密切,越远离的点关系越疏远。因此,加权平均更合理,距离越近的点权重越大,距离越远的点权重越小。计算平均值的时候,我们只需要将”中心点”作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。

image histogram (图片直方图)

以灰度图为例,我们用横轴代表 0-255 的灰度数值,竖轴代表照片中对应灰度的像素数量,这个函数图像就被称为直方图。 可以借此直观地看到灰度的分布及比例。

而大津算法就是基于直方图计算出来的。举一个极端的例子,一个只有两个灰度值的图片,其直方图只会有两个波峰。 那么其阈值应该是介于两个波峰之间的一个值。

延伸阅读,直方图在摄影中的应用

效果体验

做了一个在线版的 opencv 图像处理微信小程序,欢迎体验

参考

我是一名山东烟台的开发者,联系作者