[略略略] 2023-08-02 15:52 采纳率: 52%
浏览 7
已结题

opencv Otsu自己实现和调用函数的结果不一致是什么原因呢?

最近在学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循环算的,第二个是调用函数算的

算法原理公式:

img

输出结果:

img

  • 写回答

2条回答 默认 最新

  • 爱晚乏客游 2023-08-02 16:26
    关注

    提示你说你除以0警告了,你要看下如果是0怎么处理的问题。
    另外,opencv源码应该是CPP吧,你这个官方文档有给出源码吗?有源码的话源码图片贴出来看下,看下是不是你没带游标卡尺的问题。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 10月9日
  • 创建了问题 8月2日