Skip to content

Corrections in code for OTSU thresholding #16446

@RMukundan20

Description

@RMukundan20
System information (version)
  • OpenCV => OpenCV online documentation
  • Operating System / Platform => Not applicable
  • Compiler => Python
Detailed description

The Python code for Otsu's binarization gven in the online documentation for OpenCV Image Thresholding at
https://docs.opencv.org/3.4/d7/d4d/tutorial_py_thresholding.html
requires the following corrections:

  1. Histogram normalization should be done by dividing by the sum, not max:
    hist_norm = hist.ravel()/hist.sum()

  2. The computation of mean and variances can generate the division-by-zero run-time error when either q1 or q2 is zero. To avoid this, we must include the statement
    if q1 < 1.e-6 or q2 < 1.e-6: continue

Corrected code
img = cv.imread('noisy2.png',0)
blur = cv.GaussianBlur(img,(5,5),0)

hist = cv.calcHist([blur],[0],None,[256],[0,256])
hist_norm = hist.ravel()/hist.sum()
Q = hist_norm.cumsum()
bins = np.arange(256)
fn_min = np.inf
thresh = -1
for i in xrange(1,256):
    p1,p2 = np.hsplit(hist_norm,[i]) # probabilities
    q1,q2 = Q[i],Q[255]-Q[i] # cum sum of classes
    if  q1 < 1.e-6  or  q2  < 1.e-6:  continue
    b1,b2 = np.hsplit(bins,[i]) # weights

    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

    fn = v1*q1 + v2*q2
    if fn < fn_min:
        fn_min = fn
        thresh = i

ret, otsu = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
print( "{} {}".format(thresh,ret) )

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions