OSTU图像分割

最大类间方差法,也成大津法OSTU,它是按图像的灰度特性,将图像分成背景和目标2部分。背景和目标之间的类间方差越大,说明构成图像的2部分的差别越大,当部分目标错分为背景或部分背景错分为目标都会导致2部
分差别变小。因此,使类间方差最大的分割意味着错分概率最小。

包括以下几个步骤

求取图像的灰度直方图

# 读取图像
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大津法图像分割-LMLPHP

01-15 08:37