Otsu双阈值算法的思想与单阈值的思想类似,单阈值的思想为: g = w0(u0-u)^2+w1(u1-u)^2 使得g最大。 Otsu双阈值的思想则为: g = w0(u0-u)^2+w1(u1-u)^2+w2(u2-u)^2 使得g最大。 u0为背景区域的平均值,u1为中间区域的平均值,u2为前景区域的平均值。 w0为背景区域的概率,w1为中间区域的概率,w2为前景区域的概率。 import numpy as np import math import cv2 as cv def calc_gray_hist(image): number=0 rows,cols=image.shape gray_hist=np.zeros([256],dtype=np.uint64) for i in range(rows): for j in range(cols): gray_hist[image[i,j]]+=1 gray_hist=gray_hist/(rows*cols) return gray_hist def otsu_thresh(image): N_front=0 N_middle = 0 N_back = 0 gray_norm_hist=calc_gray_hist(image) p1 = np.zeros([256], dtype=np.float64) p2 = np.zeros([256], dtype=np.float64) k=0 m1=0 m2=0 m3=0 sum_N_front = 0 sum_N_middle = 0 sum_N_back = 0 tempg=0 threshold1=0 threshold2=0 for i in range(254): N_front+=gray_norm_hist[i] for j in range(i,256,1): for k in range(i): sum_N_front+=N_front*k if N_front!=0: m1=sum_N_front/N_front for k1 in range(i,j,1): N_middle += gray_norm_hist[k1] sum_N_middle+=N_middle*k1 if N_middle != 0: m2=sum_N_middle/N_middle for k2 in range(j,255,1): N_back += gray_norm_hist[k2] sum_N_back += N_back * k2 if N_back!= 0: m3= sum_N_back / N_back mG=N_front*m1+N_middle*m2+N_back*m3 g = N_front * math.pow(m1 - mG, 2) + N_middle * math.pow(m2 - mG, 2) + N_back * math.pow(m3 - mG, 2) if tempg<g: tempg=g threshold1=i threshold2=j sum_N_front=0 sum_N_middle=0 sum_N_back=0 N_middle=0 N_back=0 return threshold1,threshold2 if __name__=='__main__': img=cv.imread('../data/house.png',0) threshold1,threshold2=otsu_thresh(img) print(threshold1,threshold2) rows, cols = img.shape for i in range(rows): for j in range(cols): if img[i,j]<threshold1: img[i, j]=0 elif img[i, j]>=threshold2: img[i, j] = 255 else: img[i, j] = 100 cv.imwrite('img.png',img) cv.imshow('img',img) cv.waitKey() cv.destroyAllWindows()
11-29
11-29
4879
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)