自适应阈值分割(最大类间分割法 + OTSU)

1、定义

最大类间方差法是由日本学者大津(Nobuyuki Otsu)于1979年提出的,是一种自适应的阈值确定的方法,又叫大津法,简称OTSU。它是按图像的灰度特性,将图像分成背景和目标两部分,或者说,是寻找一个阈值为 T T T,将图像的颜色分为 1 , 2..... K 和 K + 1.....256 1,2.....K和K+1.....256 1,2.....KK+1.....256 两部分。

如何确定这个阈值 T T T?算法分类的原理是让背景和目标之间的类间方差最大,因为背景和目标之间的类间方差越大,说明构成图像的2部分的差别越大,错分的可能性越小。

2、公式推导

设图像包含 L L L 个灰度等级,灰度值为 i i i 的像素点的个数为 N i N_i Ni,像素点的总个数为:
N = N 0 + N 1 + . . . + N L − 1 N=N_0 + N_1 + ... + N_{L-1} N=N0+N1+...+NL1
则灰度值为 i i i 的像素点的概率为:
P i = N i N P_i = \frac{N_i}{N} Pi=NNi
由期望公式可得,图像的灰度均值为:
u T = ∑ i = 0 L − 1 i P i u_T = \sum_{i=0}^{L-1}iP_i uT=i=0L1iPi
按照图像的灰度特性,使用阈值 T T T 将图像分为目标 c 0 c_0 c0 和背景 c 1 c_1 c1 两类,则 w 0 ( T ) w_0(T) w0(T) w 1 ( T ) w_1(T) w1(T) 分别表示阈值为 T T T 时, c 0 c_0 c0 c 1 c_1 c1 发生的概率,即:
w 0 ( T ) = ∑ i = 0 T P i w 1 ( T ) = 1 − w 0 ( T ) w_0(T) = \sum_{i=0}^{T}P_i\\ w_1(T) = 1 - w_0(T) w0(T)=i=0TPiw1(T)=1w0(T)
c 0 c_0 c0 c 1 c_1 c1 的均值为:
u 0 ( T ) = ∑ i = 0 T i P i W 0 ( T ) u 1 ( T ) = u T − ∑ i = 0 T i P i w 1 ( T ) u_0(T) = \frac{\sum_{i=0}^{T}iP_i}{W_0(T)} \\ u_1(T) = \frac{u_T - \sum_{i=0}^{T}iP_i}{w_1(T)} u0(T)=W0(T)i=0TiPiu1(T)=w1(T)uTi=0TiPi
σ 2 ( T ) σ^2(T) σ2(T) 表示直方图中阈值为 T T T 的类间方差,定义为:
σ B 2 ( T ) = w 0 ( T ) [ u 0 ( T ) − u T ] 2 + w 1 ( T ) [ u 1 ( T ) − u T ] 2 σ^2_B(T) = w_0(T)[u_0(T) - u_T]^2 + w_1(T)[u_1(T) - u_T]^2 σB2(T)=w0(T)[u0(T)uT]2+w1(T)[u1(T)uT]2
最优阈值定义为类间方差最大时对应的T值,即:
σ B 2 ( T ∗ ) = max ⁡ 0 ≤ T ≤ L − 1 { σ B 2 ( T ) } σ^2_B(T^*) = \max \limits_{0 \leq T \leq L-1}\{σ^2_B(T)\} σB2(T)=0TL1max{σB2(T)}

3、代码实现

import cv2
import numpy as np
from matplotlib import pyplot as plt

image = cv2.imread(".\image\image1.png")                # 读取图片
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)          # 色彩空间转换函数

plt.subplot(1,3,1)
plt.imshow(image, "gray")
plt.title("source image")
plt.xticks([]), plt.yticks([])

plt.subplot(1,3,2)
plt.hist(image.ravel(), 256)                            # 绘制直方图
plt.title("Histogram")
plt.xticks([])
plt.yticks([])

ret1, th1 = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)  #方法选择为THRESH_OTSU
print(f'使用 OTSU 方法得到的阈值为 : {ret1}')

plt.subplot(1,3,3)
plt.imshow(th1, "gray")
plt.title("OTSU,threshold is " + str(ret1)), plt.xticks([]), plt.yticks([])
plt.show()

4、结果展示

自适应阈值分割(最大类间分割法 + OTSU)_第1张图片

你可能感兴趣的:(Python,机器学习)