1 引言
图像二值化是计算机视觉中的基础操作,它将灰度图像转换为黑白图像,常用于文档扫描、目标检测等任务。OTSU算法(大津法)是一种自动确定二值化阈值的算法,无需人工干预,通过最大化类间方差来分离前景和背景。本文将深入讲解OTSU的原理,并用Python实现完整的二值化流程。
2 原理
2.1 符号定义
OTSU算法的目标是找到一个阈值 k,将图像像素分为两类:
-
C1类:像素值 ≤ k(背景)
-
C2类:像素值 > k(前景)
定义以下变量:
-
p1、p2:C1和C2类的像素占比(概率)。
-
m1、m2:C1和C2类的平均灰度值。
-
mG:图像全局平均灰度值。
2.2 公式推导
根据均值的定义,全局均值 mG是两类均值的加权和:
注:
类间方差(Between-class Variance)衡量两类之间的分离程度,定义为:
化简得到
3 代码实现
3.1 代码
import cv2
import numpy as np
import time
import matplotlib.pyplot as plt
from PIL import Imagedef otsu_threshold(img):img_array = np.array(img)#计算直方图hist, _ = np.histogram(img_array,256,[0,256])#归一化直方图hist_norm = hist / float(np.sum(hist))#初始化best_threshold = 0max_variance = 0for threshold in range(256):w0 = np.sum(hist_norm[:threshold])w1 = np.sum(hist_norm[threshold:])if w0 == 0 or w1 ==0:continuem0 = np.sum(np.arange(0, threshold) * hist_norm[:threshold]) / w0m1 = np.sum(np.arange(threshold, 256) * hist_norm[threshold:]) / w1#计算类间方差variance = w0 * w1 * (m0 - m1) ** 2# 更新最佳阈值if variance > max_variance:max_variance = variancebest_threshold = thresholdreturn best_thresholddef apply_otsu(image_path,output_path=None):#打开图像转为灰度img = Image.open(image_path).convert('L')threshold = otsu_threshold(img)binary_img = img.point(lambda p:255 if p>threshold else 0)if output_path:binary_img.save(output_path)return binary_img, thresholdif __name__ == '__main__':image_path="test.png"output_path="output.png"binary_img, threshold = apply_otsu(image_path,output_path)binary_img.show()
3.2 实验结果展示


4 小结
OTSU算法通过最大化类间方差实现自动阈值选择,适合双峰直方图的图像。本文提供了从原理到实现的完整流程。