#自适应阈值与固定阈值对比
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('test.jpg',0)
ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,55,4)
th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,17,6)
titles =['Original','Global(v=127)','Adaptive Mean','Adaptive Gaussian']
images = [img,th1,th2,th3]
for i in range(4):
plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i],fontsize=8)
plt.xticks([]),plt.yticks([])
plt.show()
迭代法阈值分割:
步骤:
1求出图象中的最大灰度值和最小灰度值,分别记为ZMAX和ZMIN,令初始阈值T0=(ZMAX+ZMIN)/2;
2根据阈值TK将图像分割为前景和背景,分别求出两者的平均灰度值ZO和ZB;
3求出新阈值TK+1=(Z0+ZB)/2;
4若TK==TK+1,则所得即为阈值;否则转2,迭代计算;
5使用计算后的阈值进行固定阈值分割。
大津阈值 也叫最大类间方差法,是一种基于全局阈值的自适应方法。图像分为前景和背景。当取最佳阈值时候,两部分之间的差别应该是最大的,衡量差别的标准为最大类间方差。直方图有两个峰值得图像,大津法求得的T近似于两个峰值之间的低谷。
OTSU大津法:
符号说明:
T:图像(x,y)前景和背景的分割阈值;
:前景像素点数占整幅图像的比例,其平均灰度;
:背景像素点数占整幅图像的比例,其平均灰度;
:图像的总平均灰度;
g:类间方差;
:设图像的大小为,图像中像素的灰度值小于阈值T的像素个数;
:像素灰度大于阈值T 的像素个数。
等价公式:
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('test.jpg',0)
#固定阈值法
ret,th1 = cv2.threshold(img,100,255,cv2.THRESH_BINARY)
#OTSU阈值法
ret,th2 = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
#先进行高斯滤波,再使用Otsu阈值法
blur = cv2.GaussianBlur(img,(5,5),0)
ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
images = [img,0,th1,img,0,th2,blur,0,th3]
titles = ['Original','Histogram','Global(v=100)','Original','Histogram',"Otsu's","Gaussian filtered Image","Histogram","Otsu's"]
for i in range(3):
#绘制原图
plt.subplot(3,3,i*3+1)
plt.imshow(images[i*3],'gray')
plt.title(titles[i*3],fontsize=8)
plt.xticks([]),plt.yticks([])
#绘制直方图,plt,hist,ravel函数将数组降成一维
plt.subplot(3,3,i*3+2)
plt.hist(images[i*3].ravel(),256)
plt.title(titles[i*3+1],fontsize=8)
plt.xticks([]),plt.yticks([])
#绘制阈值图
plt.subplot(3,3,i*3+3)
plt.imshow(images[i*3+2],'gray')
plt.title(titles[i*3+2],fontsize=8)
plt.xticks([]),plt.yticks([])
plt.show()
test.jpg: