数字图像处理100问—04大津二值化算法(Otsu‘s Method)

本文介绍了如何利用大津二值化算法(Otsu's Method)对图像进行自动阈值处理。通过计算类间方差和类内方差,找到最佳阈值,实现图像的二值化。代码示例展示了从读取图像、灰度化到确定阈值并二值化的完整过程,最后展示二值化结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提示:内容整理自:https://github.com/gzr2017/ImageProcessing100Wen
CV小白从0开始学数字图像处理

04大津二值化算法(Otsu’s Method)

使用大津算法来二值化图像。大津算法,也被称作最大类间方差法,是一种可以自动确定二值化中阈值的算法,从类内方差和类间方差的比值计算得来:

  • 小于阈值 t 的类记作 0,大于阈值 t 的类记作 1;
  • w0 和 w1 是被阈值 t 分开的两个类中的像素数占总像素数的比率(满足 w0+w1=1);
  • S0^2, S1^2 是这两个类中像素值的方差;
  • M0, M1 是这两个类的像素值的平均值;

也就是说:

类内方差:Sw^2 = w0 * S0^2 + w1 * S1^2
类间方差:Sb^2 = w0 * (M0 - Mt)^2 + w1 * (M1 - Mt)^2 = w0 * w1 * (M0 - M1) ^2
图像所有像素的方差:St^2 = Sw^2 + Sb^2 = (const)
根据以上的式子,我们用以下的式子计算分离度:
分离度 X = Sb^2 / Sw^2 = Sb^2 / (St^2 - Sb^2)

也就是说:

argmax_{t} X = argmax_{t} Sb^2

换言之,如果使 Sb^2 = w0 * w1 * (M0 - M1) ^2 最大,就可以得到最好的二值化阈值 t。

代码如下:

1.引入库

CV2计算机视觉库

import cv2
import numpy as np

2.读入数据

img = cv2.imread("imori.jpg").astype(np.float)
H, W, C = img.shape

3.灰度化

out = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]
out = out.astype(np.uint8)

4.确定阈值

max_sigma = 0
max_t = 0

for _t in range(1, 255):
    v0 = out[np.where(out < _t)]
    m0 = np.mean(v0) if len(v0) > 0 else 0.
    w0 = len(v0) / (H * W)
    v1 = out[np.where(out >= _t)]
    m1 = np.mean(v1) if len(v1) > 0 else 0.
    w1 = len(v1) / (H * W)
    sigma = w0 * w1 * ((m0 - m1) ** 2)
    if sigma > max_sigma:
        max_sigma = sigma
        max_t = _t

5.二值化

print("threshold >>", max_t)
th = max_t
out[out < th] = 0
out[out >= th] = 255

6.保存结果

cv2.imwrite("out.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)
cv2.destroyAllWindows()

6. 二值化后结果

在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值