【youcans 的 OpenCV 例程200篇】161. OTSU 阈值处理算法的实现

OpenCV 例程200篇 总目录-202205更新
欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中


【youcans 的 OpenCV 例程200篇】161. OTSU 阈值处理算法的实现


3.3 全局阈值处理 Otsu 方法

OTSU 方法又称大津算法,使用最大化类间方差(intra-class variance)作为评价准则,基于对图像直方图的计算,可以给出类间最优分离的最优阈值。

任取一个灰度值 T,可以将图像分割为两个集合 F 和 B,集合 F、B 的像素数的占比分别为 pF、pB,集合 F、B 的灰度值均值分别为 mF、mB,图像灰度值为 m,定义类间方差为:
I C V = p F ∗ ( m F − m ) 2 + p B ∗ ( m B − m ) 2 ICV = p_F * (m_F - m)^2 + p_B * (m_B - m)^2 ICV=pF(mFm)2+pB(mBm)2
使类间方差 ICV 最大化的灰度值 T 就是最优阈值。

因此,只要遍历所有的灰度值,就可以得到使 ICV 最大的最优阈值 T。


例程 11.18:OTSU 阈值处理算法的实现

    # 11.18 OTSU 阈值处理算法的实现
    img = cv2.imread("../images/Fig1039a.tif", flags=0)

    histCV = cv2.calcHist([img], [0], None, [256], [0, 256])  # 灰度直方图
    scale = range(256)  # 灰度级 [0,255]
    totalPixels = img.shape[0] * img.shape[1]  # 像素总数
    totalGray = np.dot(histCV[:,0], scale)  # 内积, 总和灰度值
    mG = totalGray / totalPixels  # 平均灰度

    icv = np.zeros(256)
    numFt, sumFt = 0, 0
    for t in range(256):  # 遍历灰度值
        numFt += histCV[t,0]   # F(t) 像素数量
        sumFt += histCV[t,0] * t  # F(t) 灰度值总和
        pF = numFt / totalPixels  # F(t) 像素数占比
        mF = (sumFt/numFt) if numFt>0 else 0  # F(t) 平均灰度
        numBt = totalPixels-numFt  # B(t) 像素数量
        sumBt = totalGray - sumFt  # B(t) 灰度值总和
        pB = numBt / totalPixels  # B(t) 像素数占比
        mB = (sumBt/numBt) if numBt>0 else 0  # B(t) 平均灰度
        icv[t] = pF * (mF-mG)**2 + pB * (mB-mG)**2  # 灰度 t 的类间方差
    maxIcv = max(icv)  # ICV 的最大值
    maxIndex = np.argmax(icv)  # 最大值的索引

    # 阈值处理
    ret, imgBin = cv2.threshold(img, maxIndex, 255, cv2.THRESH_BINARY)  # 以 maxIndex 作为最优阈值
    ret, imgOtsu = cv2.threshold(img, mG, 255, cv2.THRESH_OTSU)  # 阈值分割, OTSU
    print("t(maxICV)={}, retOtsu={}".format(maxIndex, round(ret)))

    plt.figure(figsize=(7,7))
    plt.subplot(221), plt.axis('off'), plt.title("Origin"), plt.imshow(img, 'gray')
    plt.subplot(222, yticks=[]), plt.title("Gray Hist")  # 直方图
    plt.plot(scale, histCV[:,0]/max(histCV))  # 灰度直方图
    plt.plot(scale, icv/maxIcv)  # 类间方差图
    plt.subplot(223), plt.title("global binary(T={})".format(maxIndex)), plt.axis('off')
    plt.imshow(imgBin, 'gray')
    plt.subplot(224), plt.title("OTSU binary(T={})".format(round(ret))), plt.axis('off')
    plt.imshow(imgOtsu, 'gray')
    plt.tight_layout()
    plt.show()

在这里插入图片描述



(本节完)


版权声明:

youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/124281291)

Copyright 2022 youcans, XUPT
Crated:2022-4-18


欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中

【youcans 的 OpenCV 例程200篇】158. 阈值处理之固定阈值法
【youcans 的 OpenCV 例程200篇】159. 图像分割之全局阈值处理
【youcans 的 OpenCV 例程200篇】160. 图像处理之OTSU 方法
【youcans 的 OpenCV 例程200篇】161. OTSU 阈值处理算法的实现
【youcans 的 OpenCV 例程200篇】162. 全局阈值处理改进方法
【youcans 的 OpenCV 例程200篇】163. 基于边缘信息改进全局阈值处理
【youcans 的 OpenCV 例程200篇】164.使用 Laplace 边缘信息改进全局阈值处理
【youcans 的 OpenCV 例程200篇】165.多阈值 OTSU 处理方法
【youcans 的 OpenCV 例程200篇】166.自适应阈值处理
【youcans 的 OpenCV 例程200篇】167.基于移动平均的可变阈值处理
更多内容,请见:
【OpenCV 例程200篇 总目录-202206更新】

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Otsu阈值分割算法是一种基于图像直方图的自适应阈值分割方法,它可以自动确定分割阈值,使得分割后的两个部分之间的类间方差最大,从而达到最佳分割效果。 以下是Python实现Otsu阈值分割算法的示例代码: ```python import cv2 import numpy as np def otsu_threshold(image): # 计算图像直方图 hist, _ = np.histogram(image, bins=256) # 归一化直方图 hist_norm = hist / float(image.size) # 初始化变量 best_thresh = 0 best_var = 0 w0 = 0 u0 = 0 total_mean = np.mean(image) # 遍历所有阈值 for thresh in range(256): w1 = w0 + hist_norm[thresh] if w1 == 0: continue u1 = (w0 * u0 + thresh * hist_norm[thresh]) / w1 u2 = (total_mean - w1 * u1) / (1 - w1) var_between = w0 * (u0 - total_mean)**2 + w1 * (u1 - total_mean)**2 if var_between > best_var: best_var = var_between best_thresh = thresh w0 = w1 u0 = u1 # 返回最佳阈值 return best_thresh # 读取图像 image = cv2.imread('test.png', 0) # 应用Otsu阈值分割算法 thresh = otsu_threshold(image) binary_image = np.zeros_like(image) binary_image[image > thresh] = 255 # 显示结果 cv2.imshow('Original Image', image) cv2.imshow('Binary Image', binary_image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 其中,`otsu_threshold`函数实现Otsu阈值分割算法,输入为灰度图像,输出为最佳阈值。然后,我们可以根据最佳阈值将图像二值化,生成二值化图像。最后,使用OpenCV库的`imshow`函数显示原始图像和二值化图像。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

youcans_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值