cv2.threshold利用OSTU方法分割图像的前景和背景
OSTU方法,又称大津法或最大类间方差法,是一种在图像处理中广泛应用的自动阈值选择方法。该方法由日本学者大津(Nobuyuki Otsu)于1979年提出,旨在通过最大化前景与背景之间的类间方差来自动确定一个最佳阈值,从而将图像分割成前景和背景两部分。
OSTU方法的核心思想是寻找一个阈值T,使得图像的前景(高灰度值区域)和背景(低灰度值区域)之间具有最大的类间方差。类间方差越大,说明前景和背景的区分度越高,分割效果越好。
具体来说,OSTU方法的步骤如下:
- 计算图像的直方图:首先,计算图像的灰度直方图,即统计每个灰度级出现的频次。这有助于了解图像的整体灰度分布。
- 初始化变量:然后,初始化两个类(前景和背景),以及相关的变量,如权重(像素数量占总像素的比例)、均值和方差等。
- 迭代计算类间方差:接下来,通过迭代的方式,尝试不同的阈值T,并计算每个阈值下的类间方差。在每次迭代中,根据当前阈值T将像素分为前景和背景两类,并更新两类的权重、均值和方差。然后,计算当前阈值下的类间方差。
- 确定最佳阈值:最后,选择使类间方差最大的阈值T作为最佳阈值。这个阈值将用于将图像分割成前景和背景两部分。
OSTU方法具有自适应性强、分割效果好的优点,特别适用于目标单一的图像分割。然而,对于多目标图像或灰度分布不均匀的图像,OSTU方法可能无法获得理想的分割效果。在这种情况下,可以考虑使用其他更复杂的分割方法或结合其他预处理步骤来改善分割效果。
示例代码:
def ostu(img, save, name):
# 读入图像,转换为灰度
image = cv2.imread(img, 0)
# 高斯滤波
blurred = cv2.GaussianBlur(image, (5, 5), 0)
# 使用ostu自动计算阈值并分割
_, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 形态学后处理,可选,可以使用开,闭等操作连接区域和消除噪声
# kernel = np.ones((5, 5), np.uint8)
# closed = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
# opened = cv2.morphologyEx(closed, cv2.MORPH_OPEN, kernel)
opened = binary
# 找到二值图的轮廓
contours, _ = cv2.findContours(opened, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 在原图上画出轮廓
out = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
cv2.drawContours(out, contours, -1, (0, 0, 255), 1)
cv2.imshow('binary', binary)
cv2.imshow('out', out)
cv2.waitKey()
cv2.destroyAllWindows()
前景和背景的分割结果: