OTSU閾值分割

SwordKii發表於2020-11-16

單閾值OTSU演算法

https://zhuanlan.zhihu.com/p/124944108
OTSU演算法(大津演算法)的詳細步驟:

  1. 假設初始有個閾值 T 0 T_0 T0,並將影像分為兩個部分(閾值分割),前景F和背景B。
  2. 假設畫素的總個數為N,前景畫素個數為 N f N_f Nf,背景畫素個數為 N b N_b Nb
  3. 假設影像的總灰度級為 L − 1 L-1 L1,每個灰度級的畫素個數為 N i N_i Ni,那麼滿足如下的公式:
    P f = ∑ i = 0 i = T 0 N i N P_f = \sum ^{i=T_0} _{i=0} \frac {N_i}{N} Pf=i=0i=T0NNi
    P b = ∑ i = T 0 i = L − 1 N i N P_b = \sum ^{i=L-1} _{i=T_0} \frac {N_i}{N} Pb=i=T0i=L1NNi
  4. 前景和背景的灰度平均值分別為:
    M f = ∑ i = 0 i = T 0 i ∗ P i P f M_f = \sum ^{i=T_0} _{i=0} i * \frac {P_i}{P_f} Mf=i=0i=T0iPfPi
    M b = ∑ i = T 0 i = L − 1 i ∗ P i P b M_b = \sum ^{i=L-1} _{i=T_0} i * \frac {P_i}{P_b} Mb=i=T0i=L1iPbPi
  5. 整個影像的灰度平均值為:
    M = P f ∗ M f + P b ∗ M b M = P_f * M_f + P_b * M_b M=PfMf+PbMb
  6. 那麼,前景和背景之間的類間方差為:
    δ 2 = P f ∗ ( M f − M ) 2 + P b ∗ ( M b − M ) 2 \delta ^2 = P_f * (M_f - M)^2 + P_b * (M_b - M)^2 δ2=Pf(MfM)2+Pb(MbM)2
  7. 大津演算法的目的就是求得一個閾值,使得第六步的類間方差最大。
  8. 至於怎麼求解,可以用遍歷的方法,或者採用其他優化演算法,找出那個類間方差最大的閾值來分割即可。

https://zhuanlan.zhihu.com/p/95034826
g:類間方差(那個灰度的g最大,那個灰度就是需要的閾值t)
g = w 0 ∗ ( u 0 − u ) 2 + w 1 ∗ ( u 1 − u ) 2 g = w_0 * (u_0 - u) ^2 + w_1 * (u_1 - u) ^2 g=w0(u0u)2+w1(u1u)2
根據上面的關係,可以推出:
g = w 0 ∗ w 1 ∗ ( u 0 − u 1 ) 2 g = w_0 * w_1 * (u_0 - u_1) ^2 g=w0w1(u0u1)2
然後,遍歷每一個灰度值,找到這個灰度值對應的g,找到最大的g對應的t。

https://blog.csdn.net/u010128736/article/details/52801310

#coding:utf-8
import cv2
import numpy as np
from matplotlib import pyplot as plt

image = cv2.imread("E:/python/cv/OTSU/test.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

plt.subplot(131), plt.imshow(image, "gray")
plt.title("source image"), plt.xticks([]), plt.yticks([])
plt.subplot(132), plt.hist(image.ravel(), 256)
plt.title("Histogram"), plt.xticks([]), plt.yticks([])
ret1, th1 = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)  #方法選擇為THRESH_OTSU
plt.subplot(133), plt.imshow(th1, "gray")
plt.title("OTSU,threshold is " + str(ret1)), plt.xticks([]), plt.yticks([])
plt.show()

遺傳演算法解OTSU

遺傳演算法是一種基於自然選擇和群體遺傳機理地搜尋演算法。

它模擬了自然選擇和自然遺傳過程中發生的繁殖、交配和突變現象,將每一個可能的解看作是群體的一個個體,並將每個個體編碼,根據設定的目標函式對每個個體進行評價,給出一個適應度值。開始時隨機產生一些個體,利用遺傳運算元產生新一代的個體,新個體繼承上一代的優良性狀,逐步向更優解進化。由於遺傳演算法在每一代同時搜尋引數空間的不同區域,從而能夠使找到全域性最優解的可能性大大增加。遺傳演算法屬於啟發式演算法,無限趨近最優解並收斂。

那麼怎麼將影像分割問題抽象成遺傳問題,即怎麼將問題編碼成基因串,如何構造適應度函式來度量每條基因的適應度值。假設將影像分為m+1類,則m個閾值按順序排列起來構成一個基因串:
α = { T 1 , T 2 , . . . , T m } \alpha= \{ T_1, T_2, ..., T_m \} α={T1,T2,...,Tm}
由於灰度為0~255,所以可以使用8位二進位制程式碼表示每個閾值,此時每個基因串由長度為8*m個位元位的串組成。

將類間方差作為適應度函式,類間方差越大,適應度函式值就越高。

相關文章