美文网首页
【OPENCV】Otsu 阈值分割算法

【OPENCV】Otsu 阈值分割算法

作者: ItchyHiker | 来源:发表于2019-02-12 19:25 被阅读0次

    原理

    Otsu 的原理是最小化类间方差,从像素分布直方图的角度来看就是在像素分布直方图的峰值之间找一个点,使得两个类之间的方差最大,类内方差最小。


    Screen Shot 2019-01-28 at 12.02.02 PM.png image.png

    这个算法可以用于OCR, 车牌分割等等

    实现

    1. 这个实现是遍历每一个分割值,然后求解全局最优解,具体到工程应用也有一些优化算法。
    img = cv.imread('noisy2.png',0)
    blur = cv.GaussianBlur(img,(5,5),0)
    # find normalized_histogram, and its cumulative distribution function
    hist = cv.calcHist([blur],[0],None,[256],[0,256])
    hist_norm = hist.ravel()/hist.max()
    Q = hist_norm.cumsum()
    bins = np.arange(256)
    fn_min = np.inf
    thresh = -1
    for i in range(1,256):
        p1,p2 = np.hsplit(hist_norm,[i]) # probabilities
        q1,q2 = Q[i],Q[255]-Q[i] # cum sum of classes
        b1,b2 = np.hsplit(bins,[i]) # weights
        # finding means and variances
        m1,m2 = np.sum(p1*b1)/q1, np.sum(p2*b2)/q2
        v1,v2 = np.sum(((b1-m1)**2)*p1)/q1,np.sum(((b2-m2)**2)*p2)/q2
        # calculates the minimization function
        fn = v1*q1 + v2*q2
        if fn < fn_min:
            fn_min = fn
            thresh = i
    # find otsu's threshold value with OpenCV function
    ret, otsu = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
    print( "{} {}".format(thresh,ret) )
    

    Reference

    1. https://www.hindawi.com/journals/mse/2014/794574/
    2. https://www.hindawi.com/journals/mse/2014/794574/
    3. https://en.wikipedia.org/wiki/Otsu%27s_method

    相关文章

      网友评论

          本文标题:【OPENCV】Otsu 阈值分割算法

          本文链接:https://www.haomeiwen.com/subject/ovcajqtx.html