OSTU大津法圖像分割

OSTU圖像分割

最大類間方差法,也成大津法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()

運行結果

image-20210114215731299

左側爲我本身實現的OSTU分割法,右側爲OpenCV自帶的OSTU分割。code

相關文章
相關標籤/搜索