小言_互联网的博客

在OpenCV里实现全局阈值分割4

507人阅读  评论(0)

在前面五种类型里,都是设置根据阈值进行设置的,但是怎么样来决定阈值是多少,那是根据手动来设置的。由于很多情况之下,可能不能人工地设置阈值,那么就需要有算法来根据图像自动计算阈值。在OpenCV里已经有两种自动计算阈值的方法:THRESH_OTSUTHRESH_TRIANGLE 。首先来看THRESH_OTSU算法,它也称最大类间差法,有时也称之为大津算法。它是按图像的灰度特性,将图像分成背景和前景两部分。背景和前景之间的类间方差越大,说明构成图像的两部分的差别越大,当部分前景错分为背景或部分背景错分为前景都会导致两部分差别变小。因此,使类间方差最大的分割意味着错分概率最小。

设灰度图像灰度级是L,则灰度范围为[0,L-1]

OTSU算法计算图像的最佳阈值为:

t = Max[w0(t) * (u0(t) - u)^2 + w1(t) * (u1(t) - u)^2)]

 

其中分割的阈值为t时,w0为背景比例,u0为背景均值,w1为前景比例,u1为前景均值,u为整幅图像的均值,u=w0*u0+w1*u1

 

由于上式计算量较大,于是可以等价于t=w1*w2u1-u2^2。实现算法参考这个网站:

https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html

 

http://www.labbookpages.co.uk/software/imgProc/otsuThreshold.html

 

在使用这个类型时,它会自动计算阈值出来,因此它不会理解函数里设置的阈值,例子如下:

#python 3.7.4,opencv4.1
#蔡军生 https://blog.csdn.net/caimouse/article/details/51749579
#
import cv2
import numpy as np

#图像数据
src = np.array([[100, 157, 245], [20, 51, 250], [50, 2, 200]], np.uint8)
#阈值处理
retval, dst = cv2.threshold(src, 150, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)

print(src)
print(retval,'\n', dst)

cv2.waitKey(0)
cv2.destroyAllWindows()

结果输出如下:

[[100 157 245]

 [ 20  51 250]

 [ 50   2 200]]

100.0

 [[  0 255 255]

 [  0   0 255]

 [  0   0 255]]

在这个例子设置参数的阈值为150,但是实际上起作用的不是它,是通过OTSU算法计算出来的值100。用这个算法来处理斑马的图片:

#python 3.7.4,opencv4.1
#蔡军生 https://blog.csdn.net/caimouse/article/details/51749579
#
import cv2
import numpy as np

#图片的路径
imgname = "imgbin1.png"

#读取图片
image = cv2.imread(imgname, cv2.IMREAD_GRAYSCALE)

#图片的高度和宽度
h,w = image.shape[:2]
print('imagesize={}-{}'.format(w,h))

#显示原图
cv2.imshow("Image",image)

#阈值分割
retval, out = cv2.threshold(image, 100, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
print(retval)
cv2.imshow("out",out)


cv2.waitKey(0)
cv2.destroyAllWindows()

结果输出如下:

输入图片

输出图片

 

在这个例子里,自动找到的阈值是99

https://blog.csdn.net/caimouse/article/details/51749579

 


转载:https://blog.csdn.net/caimouse/article/details/101448225
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场