opencv自动阈值分割

#自适应阈值与固定阈值对比
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)前景和背景的分割阈值;

\omega _{1}:前景像素点数占整幅图像的比例,其平均灰度\mu _{1}

\omega _{2}:背景像素点数占整幅图像的比例,其平均灰度\mu _{2}

\mu:图像的总平均灰度;

g:类间方差;

N_{1}:设图像的大小为M\times N,图像中像素的灰度值小于阈值T的像素个数;

N_{2}:像素灰度大于阈值T 的像素个数。

g=\omega _{1}\times (\mu -\mu _{1})^{2}+\omega _{2}\times (\mu -\mu _{2})^{2}

等价公式:

g=\omega _{1}\times \omega _{2}\times (\mu _{1}-\mu _{2})^{2}

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:

猜你喜欢

转载自blog.csdn.net/winggyn/article/details/113090592