OpenCV实战 | 一文剖析图像阈值化方法——adaptiveThreshold thresholdTHRESH_OTSU

Posted 行路南

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV实战 | 一文剖析图像阈值化方法——adaptiveThreshold thresholdTHRESH_OTSU相关的知识,希望对你有一定的参考价值。

图像阈值化,是指根据图像内像素点强度的分布规律设置一个阈值,并根据像素点强度高于阈值或者低于阈值而进行一些处理。例如,输入是一张灰度图和一个阈值 T T T,当图中像素值大于阈值 T T T,则输出图像对应像素设置为255(白色);当图中像素值小于等于阈值 T T T,则输出图像对应像素设置为0(黑色),这样通过阈值化就得到了一个二值化的图像。阈值化作为一种非常普遍使用的图像预处理方式,有利于我们在图像中定位到我们的目标对象。

从上述阈值化的定义中,我们会发现存在两个关键问题:

  • 合适的阈值如何设置?
  • 阈值设置后,基于像素点与阈值的关系而进行的处理方式都有哪些?

1. 手动设置阈值

最简单粗暴的方式莫过于手动设置阈值。当我们拿到一张彩色图像并转换到灰度图后,我们可以打印出灰度图每个图像位置的灰度值。我们可以不断地尝试阈值,从而使得我们的目标对象被提取地很好。

在OpenCV中提供了阈值化的函数

double cv::threshold	(	InputArray 	src,
                            OutputArray 	dst,
                            double 	thresh,
                            double 	maxval,
                            int 	type 
                         )	
参数参数含义
src输入图像(支持多通道)
dst输出图像
thresh手动设置的阈值
maxval图像像素的最大值
type阈值处理的方式,见下图

c++示例代码

// 原始图像
Mat src = imread("/home/user/1.jpg");
// 转为灰度图
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
// 阈值化,像素点强度>200的设置为255,小于等于200的设置为0
Mat bw;
threshold(gray, bw, 200, 255, THRESH_BINARY);

手动设置阈值在针对一张特定图像的处理时,虽然我们会尝试若干次,但通常我们还是可以基本找到一个理想的值。但它的主要弊端是它的泛化值不好,可能在这张图像上效果很不错,换到另一张图像效果就大打折扣,原因可能只是另一张图像拍摄的光线、角度稍有不同等等。

因此我们需要有一种自动确定阈值的方法,能根据图像中像素强度的规律,找到一个合理的阈值。

2. OTSU 大津阈值法

大津阈值法假定图像中包含前景像素和背景像素,于是它计算能够将两类像素分类的最佳阈值,从而使得它们的类内方差最小,并证明了类内方差最小等价于类间方差最大。

为了形象的说明大津阈值法的效果,我们先举一个例子,让大家有一个直观的理解,最后我们会给出严谨的证明。

大津算法,是逐一计算每个阈值下的最小类内方差,找到最小的类内方差的阈值就是我们期望的阈值。

咱们以阈值 T = 3 T=3 T=3为例,来计算该阈值下的类内方差。

  • 像素值小于等于3的为背景,背景像素的像素数量权重 w b w_b wb、灰度均值 μ b \\mu_b μb和灰度方差 σ b 2 \\sigma_b^2 σb2计算如下:

n b = 20 + 2 + 12 + 4 = 38 n = 8 ∗ 8 = 64 w b = n b n = 38 64 μ b = 0 ∗ 20 + 1 ∗ 2 + 2 ∗ 12 + 3 ∗ 4 n b = 38 38 = 1 σ b 2 = ( 0 − μ b ) 2 ∗ 20 + ( 1 − μ b ) 2 ∗ 2 + ( 2 − μ b ) 2 ∗ 12 + ( 3 − μ b ) 2 ∗ 4 n b = 48 38 = 1.26 n_b = 20 + 2 + 12 + 4 = 38 \\\\ n = 8 * 8 = 64 \\\\ w_b = \\frac{n_b}{n} = \\frac{38}{64} \\\\ \\mu_b = \\frac{0 * 20 + 1 * 2 + 2 * 12 + 3 * 4}{n_b} = \\frac{38}{38} = 1\\\\ \\sigma_b^2 = \\frac{(0-\\mu_b)^2 * 20 +(1-\\mu_b)^2 * 2+(2-\\mu_b)^2 * 12 +(3-\\mu_b)^2*4}{n_b} = \\frac{48}{38} = 1.26 nb=20+2+12+4=38n=88=64wb=nnb=6438μb=nb020+12+212+34=3838=1σb2=nb(0μb)220+(1μb)22+(2μb)212+(3μb)24=3848=1.26

  • 像素值大于3的为前景,前景像素的像素数量权重 w f w_f wf、灰度均值 μ f \\mu_f μf和灰度方差 σ f 2 \\sigma_f^2 σf2计算如下:

n f = 16 + 10 = 26 w f = n f n = 24 64 μ f = 4 ∗ 16 + 5 ∗ 10 n f = 114 24 σ f 2 = ( 4 − μ f ) 2 ∗ 16 + ( 5 − μ f ) 2 ∗ 10 n f = 9.625 24 = 0.4 n_f =16 + 10 = 26 \\\\ w_f = \\frac{n_f}{n} = \\frac{24}{64} \\\\ \\mu_f = \\frac{4 * 16 + 5 * 10}{n_f} = \\frac{114}{24}\\\\ \\sigma_f^2 = \\frac{(4-\\mu_f)^2 * 16 +(5-\\mu_f)^2 * 10}{n_f} = \\frac{9.625}{24} = 0.4 nf=16+10=26wf=nnf=6424μf=nf416+510=24114σf2=nf(4μf)216+(5μf)210=249.625=0.4