python大津アルゴリズムの実現

1589 ワード

参考文献:https://blog.csdn.net/u012771236/article/details/44975831size:画像総画素個数u:画像の平均階調w 0:前景画素点が全体の画像サイズに占める割合u 0:前景画素点の平均値w 1:背景画素点が全体の画像サイズに占める割合u 0:背景画素点の平均値g:クラス間分散
u=w 0*u 0+w 1*u 1(1)g=w 0*(u-u 0)^2+w 1*(u-u 1)^2(2)を(1)に代入(2)し、g=w 0*w 1*(u 0-u 1)^2
import numpy as np
import cv2
import matplotlib.pyplot as plt  # plt       


def OTSU_enhance(img_gray, th_begin=0, th_end=256, th_step=1):
    assert img_gray.ndim == 2, "must input a gary_img"

    max_g = 0
    suitable_th = 0
    for threshold in range(th_begin, th_end, th_step):
        bin_img = img_gray > threshold
        print(bin_img)
        bin_img_inv = img_gray <= threshold
        fore_pix = np.sum(bin_img)
        back_pix = np.sum(bin_img_inv)
        if 0 == fore_pix:
            break
        if 0 == back_pix:
            continue

        w0 = float(fore_pix) / img_gray.size
        print(img_gray*bin_img)
        u0 = float(np.sum(img_gray * bin_img)) / fore_pix
        w1 = float(back_pix) / img_gray.size
        u1 = float(np.sum(img_gray * bin_img_inv)) / back_pix
        # intra-class variance
        g = w0 * w1 * (u0 - u1) * (u0 - u1)
        if g > max_g:
            max_g = g
            suitable_th = threshold
    return suitable_th


img1 = cv2.imread('2.jpg')
img = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
print(OTSU_enhance(img))
ret, binary = cv2.threshold(img, 120, 255, cv2.THRESH_BINARY)
cv2.namedWindow('a', 0)
cv2.resizeWindow('a', 640, 480)
cv2.imshow('a', binary)
cv2.waitKey(0)


注意bin_imgはブールタイプです.