6.4 數字圖像處理——大津法及Python實現


對於給定的閾值\(T\),可以將圖像分為目標和背景。其中背景點數占圖像比例為 \(p_0\),平均灰度值為 \(m_0\)。而目標點數占圖像比例為 \(p_1\),平均灰度值為 \(m_1\),其中滿足

\[p_0 + p_1 = 1 \]

整幅圖像的平均灰度值為常數,跟閾值無關,且為

\[\overline m = p_0m_0 + p_1m_1 \]

類間方差為

\[\sigma^2 = p_0(m_0 - \overline m)^2 + p_1(m_1 - \overline m)^2 \]

代入 \(p_0 + p_1 = 1\)\(\overline m\),可化簡為

\[\sigma^2 = p_0p_1(m_0 - m_1)^2 \]

遍歷灰度值,找出能使 \(\sigma^2\) 最大的值。

大津法步驟

(1) 初始化方差為 \(S = -1\)
(2) 對灰度值為 \(0~255\) 的整數的圖像, 遍歷每個灰度值 \(T\),每次做第(3)步操作;
(3) 計算以 \(T\) 為閾值時候的類間方差,如果大於 \(S\),更新 \(S\) 並記錄 \(T\)
(4) 獲得使類間方差最大的 \(S\)

效果

drawing

實現

1. 調用 OpenCV庫

img = cv.imread(img_path, 0)       # img_path 為圖片路徑
th, img_bin = cv.threshold(img, -1, 255, cv.THRESH_OTSU) # img_bin 為二值化結果

2. 自己實現

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

def show(img):
    if img.ndim == 2:
        plt.imshow(img, cmap='gray')
    else:
        img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
        plt.imshow(img)
    plt.show()

# 正式開始
img = cv.imread('pic/eagle500x500.jpg', 0)

Sigma = -1
T = 0

for t in range(0, 256):
    bg  = img[img <= t]
    obj = img[img > t]
    
    p0 = bg.size / img.size
    p1 = obj.size / img.size
    
    m0 = 0 if bg.size == 0 else bg.mean()
    m1 = 0 if obj.size == 0 else obj.mean()
    
    sigma = p0 * p1 * (m0 - m1)**2
    
    if sigma > Sigma:
        Sigma = sigma
        T = t
T = int(T)

# 此時 T 即為最佳閾值
print(f"Best threshold = {T}")

說明:

  1. 未經許可,謝絕轉載。
  2. 本教程為《數字圖像處理Python OpenCV實戰》的配套代碼相關內容。
    免費視頻教程為0-6章(標題號≤6),可在此處點擊觀看。
    所有課件及源代碼可在此處下載:
    鏈接:https://pan.baidu.com/s/198PySe_vebO3e06idHSQ6g
    提取碼:11o4
    有問題可在QQ群(1079300899)指出,進群答案:數字圖像處理。在本文評論指出可能導致回復很晚。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM