【图像处理】 最大类间方差算法(Otus算法)

【图像处理】 最大类间方差算法(Otus算法)

Otsu算法的原理

最大类间方差法(Otus算法),可以自动的选取二值化的阈值。
它的原理如下:

  1. 假设一副灰度图有 L L 个灰度级,即 [ 1 , 2 , 3 , . . . L ] [1,2,3,...L] ,灰度级为 i i 的像素点有 n i n_i 个,那么总的像素点个数 N = n 1 + n 2 + . . . + n l N = n_1 + n_2 +...+n_l 。那么一个像素点灰度级为 i i 的概率为: p i = n i N ( p i > 0 i = 1 L p i = 1 ) p_i = \dfrac{n_i}{N} (p_i>0,\displaystyle\sum_{i = 1}^{L}p_i = 1)
  2. 现在假设通过一个灰度级 k k 将这些像素点划分为两类 C 0 C_0 C 1 C_1 [ 1 , 2 , . . . k ] [1,2,...k] C 0 C_0 ,二值化为 0 0 [ k + 1 , k + 2 , . . . L ] [k+1,k+2,...L] C 1 C_1 ,二值化为 255 255 。Otsu算法就是自动的找到这个算法认为的最优的阈值 k k
  3. C 0 C_0 C 1 C_1 两类,每一类出现的概率以及各类的平均灰度级分别由下面的式子给出:
    ω 0 = P r ( C 0 ) = C 0 = i = 1 k p i = ω ( k ) \omega_0=P_r(C_0)=C_0类出现的概率=\displaystyle\sum_{i = 1}^{k}p_i = \omega(k)
    ω 1 = P r ( C 1 ) = C 1 = i = k + 1 L p i = 1 ω ( k ) \omega_1=P_r(C_1)=C_1类出现的概率=\displaystyle\sum_{i = k+1}^{L}p_i =1- \omega(k)
    μ 0 = i = 1 k i P r ( i C 0 ) = i = 1 k i p i ω 0 = C 0 = μ ( k ) ω ( k ) \mu_0=\displaystyle\sum_{i = 1}^{k}i*P_r( i|C_0)=\displaystyle\sum_{i = 1}^{k}i* \dfrac{p_i}{\omega_0}=C_0类的平均灰度级=\dfrac{\mu(k)}{\omega(k)}
    μ 1 = i = k + 1 L i P r ( i C 1 ) = i = k + 1 L i p i ω 1 = C 1 = μ T μ ( k ) 1 ω ( k ) \mu_1=\displaystyle\sum_{i = k+1}^{L}i*P_r( i|C_1)=\displaystyle\sum_{i = k+1}^{L}i* \dfrac{p_i}{\omega_1}=C_1类的平均灰度级=\dfrac{\mu_T-\mu(k)}{1-\omega(k)}
    其中:
    μ ( k ) = i = 1 k i p i \mu(k)=\displaystyle\sum_{i = 1}^{k}i*p_i ,是 1 k 1到k 的平均灰度级。
    μ T = i = 1 L i p i \mu_T=\displaystyle\sum_{i = 1}^{L}i*p_i ,是整幅图的平均灰度级。
  4. 容易验证:
    ω 0 μ 0 + ω 1 μ 1 = μ T \omega_0\mu_0+\omega_1\mu_1=\mu_T ω 0 + ω 1 = 1 \omega_0+\omega_1=1
  5. C 0 C_0 C 1 C_1 各自的类内方差如下:
    σ 0 2 = i = 1 k ( i μ 0 ) 2 P r ( i C 0 ) = i = 1 k ( i μ 0 ) 2 p i ω 0 \sigma_0^2=\displaystyle\sum_{i = 1}^{k}(i-\mu_0)^2P_r(i|C_0)=\displaystyle\sum_{i = 1}^{k}(i-\mu_0)^2\dfrac{p_i}{\omega_0}
    σ 1 2 = i = k + 1 L ( i μ 1 ) 2 P r ( i C 1 ) = i = k + 1 L ( i μ 1 ) 2 p i ω 1 \sigma_1^2=\displaystyle\sum_{i = k+1}^{L}(i-\mu_1)^2P_r(i|C_1)=\displaystyle\sum_{i = k+1}^{L}(i-\mu_1)^2\dfrac{p_i}{\omega_1}
  6. 所以整幅图片的类内方差两个类的类间方差图片的总方差,分别如下:
    σ W 2 = = ω 0 σ 0 2 + ω 1 σ 1 2 \sigma_W^2=整幅图片的类内方差=\omega_0\sigma_0^2+\omega_1\sigma_1^2
    σ B 2 = = ω 0 ( μ 0 μ T ) 2 + ω 1 ( μ 1 μ T ) 2 \sigma_B^2=两个类的类间方差=\omega_0(\mu_0-\mu_T)^2+\omega_1(\mu_1-\mu_T)^2
    跟据4.中两个等式,可以将 σ B 2 \sigma_B^2 化简为 ω 0 ω 1 ( μ 1 μ 0 ) 2 \omega_0\omega_1(\mu_1-\mu_0)^2
    σ T 2 = = i = k + 1 L ( i μ T ) 2 p i \sigma_T^2=图片的总方差=\displaystyle\sum_{i = k+1}^{L}(i-\mu_T)^2p_i
  7. 因为 σ T 2 \sigma_T^2 k k 无关。 σ W 2 \sigma_W^2 二阶统计(类方差),而 σ B 2 \sigma_B^2 一阶统计(类均值)。所以 σ B 2 \sigma_B^2 ,即类间方差是最简单的判断 k k 选取好坏的评判标准。
  8. 所以Otus算法遍历 k k ,最后选取使 σ B 2 \sigma_B^2 最大的 k k 作为阈值。

opencv中的Otsu算法

_, img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
//在python opencv的二值化函数cv.threshold中,通过最后的参数选择使用Otus算法
//第一个输入是输入的灰度图像
//第二个参数是阈值,因为这个由算法自动选择,所以填0
//第三个参数是最大值,即大于阈值的像素点都等于这个值,小于阈值的都是0
//第一个返回值就是所取的阈值,如果不用Otus算法,第一个返回值也是我们选取的阈值
//第二个返回值是二值图

结语

如果您有修改意见或问题,欢迎留言或者通过邮箱和我联系。
手打很辛苦,如果我的文章对您有帮助,转载请注明出处。

猜你喜欢

转载自blog.csdn.net/Zhang_Chen_/article/details/91408969