最大类间方差法,也成大津法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