最大類間方差法,也成大津法OSTU,它是按圖像的灰度特性,將圖像分紅背景和目標2部分。背景和目標之間的類間方差越大,說明構成圖像的2部分的差異越大,當部分目標錯分爲背景或部分背景錯分爲目標都會致使2部
分差異變小。所以,使類間方差最大的分割意味着錯分機率最小。python
包括如下幾個步驟ui
# 讀取圖像 o_img = cv2.imread('source/house.png') # 灰度化 img = cv2.cvtColor(o_img, cv2.COLOR_BGR2GRAY) # 獲取圖片的長寬 u, v = img.shape[:2] # 求取直方圖 channel, bins = np.histogram(img.ravel(), 256, [0, 256])
# 初始化閾值 threshold = 0 # 求取灰度值的和 for i in range(256): threshold += i * channel[i] # 計算全局最佳閾值 threshold = int(threshold / (u * v))
# 初始化輸出圖像 out = np.zeros((u, v), np.uint8) for i in range(u): for j in range(v): # 若是大於閾值就將其設定爲白色,不然就爲黑色 if img[i][j] > threshold: out[i][j] = 255 else: out[i][j] = 0
import cv2 import numpy as np o_img = cv2.imread('source/house.png') # 灰度化 img = cv2.cvtColor(o_img, cv2.COLOR_BGR2GRAY) u, v = img.shape[:2] channel, bins = np.histogram(img.ravel(), 256, [0, 256]) threshold = 0 for i in range(256): threshold += i * channel[i] threshold = int(threshold / (u * v)) out = np.zeros((u, v), np.uint8) for i in range(u): for j in range(v): if img[i][j] > threshold: out[i][j] = 255 else: out[i][j] = 0 ret, mask_front = cv2.threshold(img, 175, 255, cv2.THRESH_OTSU) cv2.imshow('OSTU', mask_front) cv2.imshow('out', out) cv2.waitKey(0) cv2.destroyAllWindows()
左側爲我本身實現的OSTU分割法,右側爲OpenCV自帶的OSTU分割。code