大津二值化算法自动确定二值化图像时的阈值

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

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

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

posted on 2020-03-14 19:10  我坚信阳光灿烂  阅读(867)  评论(0编辑  收藏  举报

导航