zoukankan      html  css  js  c++  java
  • 大津二值化算法自动确定二值化图像时的阈值

    大津算法,也被称作最大类间方差法,是一种自动确定二值化阈值的算法。

    在这里作者不介绍算法推导的过程,算法推导过程网络上有许多介绍,这里只给出算法最终推导出的结论:

    S_{b} ^2 = omega _{0} * omega _{1} * (M_{0}-M_{1} )^2

    使得左侧 S_{b}^2 的值最大,就可以得到最好的二值化阈值 t

    其中,omega _{0} 和 omega _{1} 是被阈值分开的两个类中的像素数占总像素数的比率。M_{0}和 M_{1}分别是这两个类的像素值的平均值。


    废话不多说,直接上python代码:

    import cv2
    
    import numpy as np
    
    def BGR2GRAY(img):
    
      b = img[:, :, 0].copy()
    
      g = img[:, :, 1].copy()
    
      r = img[:, :, 2].copy()
    
      # Gray scale
    
      out = 0.2126 * r + 0.7152 * g + 0.0722 * b
    
      out = out.astype(np.uint8)
    
      return out
    
    # Otsu Binarization
    
    def otsu_binarization(img, th=128):
    
      max_sigma = 0
    
      max_t = 0
    
      # determine threshold
    
      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
    
      # Binarization
    
      print("threshold >>", max_t)
    
      th = max_t
    
      out[out < th] = 0
    
      out[out >= th] = 255
    
      return out
    
    # Read image
    
    img = cv2.imread("../paojie.jpg").astype(np.float32)
    
    H, W, C =img.shape
    
    # Grayscale
    
    out = BGR2GRAY(img)
    
    # Otsu's binarization
    
    out = otsu_binarization(out)
    
    # Save result
    
    cv2.imwrite("out.jpg", out)
    
    cv2.imshow("result", out)
    
    cv2.waitKey(0)
    
    cv2.destroyAllWindows()

    输出:

    threshold >> 157


    原图

    大津二值化后图像

    当然,opencv已经为我们实现了 Otsu's binarization 算法,我们可以直接调用它:

    import cv2
    
    import numpy as np
    
    def BGR2GRAY(img):
    
      b = img[:, :, 0].copy()
    
      g = img[:, :, 1].copy()
    
      r = img[:, :, 2].copy()
    
      # Gray scale
    
      out = 0.2126 * r + 0.7152 * g + 0.0722 * b
    
      out = out.astype(np.uint8)
    
      return out
    
    # Read image
    
    img = cv2.imread("../paojie.jpg").astype(np.float32)
    
    # Grayscale
    
    out = BGR2GRAY(img)
    
    # Otsu's binarization of Opencv
    
    ret2,th2 = cv2.threshold(out,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    
    print("threshold >>", ret2)
    
    # Save result
    
    cv2.imwrite("out.jpg", th2)
    
    cv2.imshow("result", th2)
    
    cv2.waitKey(0)
    
    cv2.destroyAllWindows()

    结果类似

    threshold >> 156.0

    输出图像在此不予展示


    参考:https://www.jianshu.com/p/67522af22197

  • 相关阅读:
    语音合成
    JAVA的18条BASE
    Java关键字final、static使用总结
    JAVA学习之路:不走弯路,就是捷径
    每个java初学者都应该搞懂的问题
    Tomcat5.5.9+JSP经典配置实例
    FineUI控件集合
    AngularJS基础
    数据库优化方案之SQL脚本优化
    数据库分库分表策略之MS-SQL读写分离方案
  • 原文地址:https://www.cnblogs.com/wojianxin/p/12493658.html
Copyright © 2011-2022 走看看