最近在学opencv,跟着官方文档敲,这是Otsu算法的实现,请问为什么自己实现的和调用函数得出的的答案不一样呢呢,麻烦dl们解答一下,非常感谢
#Otsu's工作原理
import cv2
import numpy as np
img=cv2.imread('./picture3.jpg',0)
blur=cv2.GaussianBlur(img,(5,5),0)
hist=cv2.calcHist([blur],[0],None,[256],[0,256])
hist_norm=hist.ravel()/hist.max()
#归一化,形成各值出现的概率p(X=x)
#ravel():将数组拉成一维数组
Q=hist_norm.cumsum()
#形成概率分布p(X<=x)
bins=np.arange(256)
#直方图坐标轴上x轴各点
fn_min=np.inf
#记录至今最小的组内方差,Otsu是找到使组内方差加权和最小的分割点,先设为最大,后面逐步更新
thresh=-1
#每次记录当前组内方差加权和最小的分割点
for i in range(256):
p1,p2=np.hsplit(hist_norm,[i])
q1,q2=Q[i],Q[-1]-Q[i]
b1,b2=np.hsplit(bins,[i])
#i值
u1,u2=np.sum(b1*p1)/q1,np.sum(b2*p2)/q2
v1,v2=np.sum((b1-u1)**2*p1/q1),np.sum((b2-u2)**2*p2/q2)
#两个组内方差
fn_temp=q1*v1+q2*v2
if fn_temp<fn_min:
fn_min=fn_temp
thresh=i
ret,otsu=cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
print(thresh,ret)
#第一个是前面自己定义的for循环算的,第二个是调用函数算的
算法原理公式:

输出结果:
