Otsu‘s Thresholding的工作原理「建议收藏」

Otsu‘s Thresholding的工作原理「建议收藏」Otsu’sThresholding的工作原理

大家好,又见面了,我是你们的朋友全栈君。

Otsu’s Thresholding的工作原理

在双峰图像(像素的直方图只包含两个峰值),一个好的阈值将在这两个值的中间。Otsu算法就是从图像的像素直方图中确定了一个最佳的全局阈值 t t t,可以最小化weighted within-class variance加权类内方差。

σ w 2 ( t ) = q 1 ( t ) σ 1 2 ( t ) + q 2 ( t ) σ 2 2 ( t ) \sigma_w^2(t) = q_1(t)\sigma_1^2(t)+q_2(t)\sigma_2^2(t) σw2​(t)=q1​(t)σ12​(t)+q2​(t)σ22​(t)
权重:
q 1 ( t ) = ∑ i = 1 t P ( i ) & q 2 ( t ) = ∑ i = t + 1 I P ( i ) q_1(t) = \sum_{i=1}^{t} P(i) \quad \& \quad q_2(t) = \sum_{i=t+1}^{I} P(i) q1​(t)=i=1∑t​P(i)&q2​(t)=i=t+1∑I​P(i)
均值:
μ 1 ( t ) = ∑ i = 1 t i P ( i ) q 1 ( t ) & μ 2 ( t ) = ∑ i = t + 1 I i P ( i ) q 2 ( t ) \mu_1(t) = \sum_{i=1}^{t} \frac{iP(i)}{q_1(t)} \quad \& \quad \mu_2(t) = \sum_{i= t+1}^{I} \frac{iP(i)}{q_2(t)} μ1​(t)=i=1∑t​q1​(t)iP(i)​&μ2​(t)=i=t+1∑I​q2​(t)iP(i)​
方差:
σ 1 2 ( t ) = ∑ i = 1 t [ i − μ 1 ( t ) ] 2 P ( i ) q 1 ( t ) & σ 2 2 ( t ) = ∑ i = t + 1 I [ i − μ 2 ( t ) ] 2 P ( i ) q 2 ( t ) \sigma_1^2(t) = \sum_{i=1}^{t} [i-\mu_1(t)]^2 \frac{P(i)}{q_1(t)} \quad \& \quad \sigma_2^2(t) = \sum_{i=t+1}^{I} [i-\mu_2(t)]^2 \frac{P(i)}{q_2(t)} σ12​(t)=i=1∑t​[i−μ1​(t)]2q1​(t)P(i)​&σ22​(t)=i=t+1∑I​[i−μ2​(t)]2q2​(t)P(i)​

import cv2 as cv
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
img = cv.imread('./images/kakaka.jpg')
img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
img_gray = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
#img_blur = cv.GaussianBlur(img_gray, (5, 5), 0)

在这里插入图片描述

Numpy Otsu’s thresholding
hist_cv = cv.calcHist([img_gray],[0],None,[256],[0,256]) # (256,1)
hist_np = np.bincount(img_gray.ravel(), minlength=256)   # (256,)
hist_norm = hist_np/hist_np.sum()
Q = hist_norm.cumsum()
bins = np.arange(256)
fn_min = np.inf
thresh = -1

for i in range(1, 256):
    p1, p2 = np.hsplit(hist_norm, [i])
    q1, q2 = Q[i], 1.0 - Q[i]    # Q[255] = 1.0
    if q1 < 1.e-6 or q2 < 1.e-6:
        continue
    b1, b2 = np.hsplit(bins, [i])
    # means and variances
    m1, m2 = np.sum(p1*b1)/q1, np.sum(p2*b2)/q2
    v1, v2 = np.sum(((b1 - m1)**2)*p1)/q1, np.sum(((b2 - m2)**2)*p2)/q2
    # weighted within-class variances
    fn = v1*q1 + v2*q2
    if fn < fn_min:
        fn_min = fn
        thresh = i
print("threshold t : %d"%thresh)
threshold t : 115

在这里插入图片描述

mask = np.zeros_like(img_gray)
mask[np.where(img_gray >= 115)] = 1
plt.imshow(img*mask.reshape(245, 250, 1))

在这里插入图片描述

OpenCV otsu’s thresholding
ret, otsu = cv.threshold(img_gray, 0, 255, cv.THRESH_BINARY+cv.THRESH_OTSU)
print("threshold t : %d"%ret)
threshold t : 114
ROI
img_roi = cv.bitwise_and(img, img ,mask = otsu)

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/142985.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • vue双向数据绑定原理面试_vue双向绑定原理

    vue双向数据绑定原理面试_vue双向绑定原理vue.js则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。vue实现双向数据绑定的原理就是利用了Object.defineProperty()这个方法重新定义了对象获取属性值(get)和设置属性值(set…

    2022年10月18日
  • 神奇的CSS3按钮特效

    点击这里查看效果以下是源代码:1234567CSS3神奇的按钮-柯乐义89678695696697请使用支持CSS3的浏览器查看本页。原文698699700701

    2021年12月20日
  • 劳动节,让我们劳动起来!

    劳动节,让我们劳动起来!

    2021年5月27日
  • django动态路由_路由器可以当转换器用吗

    django动态路由_路由器可以当转换器用吗自定义路径转换器有时候上面的内置的url转换器并不能满足我们的需求,因此django给我们提供了一个接口可以让我们自己定义自己的url转换器django内置的路径转换器源码解析在我们自定义路由转

    2022年8月7日
  • pycharm 程序调试快捷键「建议收藏」

    pycharm 程序调试快捷键「建议收藏」pycharm程序调试快捷键stepinto(F5):进入子函数,不管是遇到系统的子函数还是自己写的子函数,都会进入。stepover(F6):进入子函数,跳过系统的子函数而只进入自己写的子函数stepintomycode(Alt+shift+F7):跳过所有子函数runtocursor(Ctrl+R):运行到光标所在处resumeprogram(F9):运行到下一个断点(程序运行过程中依然可以添加断点)…

    2022年8月25日
  • STM32CubeMX学习–(5)SPI读写W25Q128

    CUBE配置SPI配置引脚配置参数配置点击生成代码代码修改 uint8_tData1[4]={0x90,0x00,0x00,0x00}; uint8_tData2[2]={0x00,0x00}; uint8_tRxData[2]={0x00,0x00};/****************************/while(1){ HAL_GP…

    2022年4月13日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号