opencv-pytho(9):图像阈值

来源:互联网 发布:胡宗南保卫延安知乎 编辑:程序博客网 时间:2024/06/06 01:55

本节将学习简单阈值,自适应阈值,Otsu's二值化等

学习的函数有cv2.threshold,cv2.adaptiveThreshold等

1、简单阈值

函数原型:cv2.treshold(src,x,y,method)

src:原函数 ,应为灰度值  x:指对像素值进行分类的阈值   y:当像素高于(或者小于)阈值时会被赋予的新值

method:

cv2.THRESH_BINARY   cv2.THRESH_BINARY  cv2.THRESH_TRUNC    cv2.THRESH_TOZERO  cv2.THRESH_TOZERO_INV


代码:

import cv2import numpy as npfrom matplotlib import pyplot as plt img=cv2.imread('C:\\Users\\WLX\\Desktop\\15.png',0)ret,thresh1=cv2.threshold(img,127,255,cv2.THRESH_BINARY)ret,thresh2=cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)ret,thresh3=cv2.threshold(img,127,255,cv2.THRESH_TRUNC)ret,thresh4=cv2.threshold(img,127,255,cv2.THRESH_TOZERO)ret,thresh5=cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)titles=['oringinal Image' ,'BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']images=[img,thresh1,thresh2,thresh3,thresh4,thresh5]for i in range(6):    plt.subplot(2,3,i+1)    plt.imshow(images[i],'gray')    plt.title(titles[i])    plt.xticks([])    plt.yticks([])plt.show()
结果:


2、自适应阈值

 整幅图像用同一个阈值这种方法并不适用所有情况,尤其当同一副图像上的不同部分具有不同的亮度时。这种情况我们需要采用自适应阈值。因此在同一副图像上的不同区域采用不同的阈值。

函数原型:

dst = cv2.adaptiveThreshold(src, maxval, thresh_type, type, Block Size, C)

  • src: 输入图,只能输入单通道图像,通常来说为灰度图
  • dst: 输出图
  • maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
  • thresh_type: 阈值的计算方法,包含以下2种类型:cv2.ADAPTIVE_THRESH_MEAN_C; cv2.ADAPTIVE_THRESH_GAUSSIAN_C.
  • type:二值化操作的类型,与固定阈值函数相同,但仅包含以下2种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV
  • Block Size: 图片中分块的大小,用来计算阈值的像素邻域大小:3,5,7
  • C :阈值计算方法中的常数项

自适应阈值:  对方法CV_ADAPTIVE_THRESH_MEAN_C,先求出块中的均值,再减掉C。

                       对方法 CV_ADAPTIVE_THRESH_GAUSSIAN_C ,先求出块中的加权和(gaussian), 再减掉C。

参见    点击打开链接

代码:

import cv2import numpy as npfrom matplotlib import pyplot as plt img=cv2.imread('C:\\Users\\WLX\\Desktop\\7.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,11,2)th3=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)titles=['Original Image','Global Thresholding(v=127)','Adaptive Mean Thresholding','Adaptive Gaussian Thresholding']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])    plt.xticks([])    plt.yticks([])plt.show()
结果:


3、Otsu's二值化

当处理双峰图像时,我们使用Otsu二值化。它对一副双峰图像自动根据直方图计算一个阈值。(对于非双峰图像这种方法并不适用)

这里会用到cv2.threshold(),但需要传入一个参数(flag),cv2.THRESH_OTSU。这里把阈值设为0.然后算法会找到最优阈值,这个最优阈值返回值retVal。如果不适用Otsu二值化,返回的retVal值与设定的阈值相等。

下面的例子中,输入图像是一副带有噪声的图像,第一种方法,我们设127为全局阈值。第二种方法,我们直接使用Otsu二值化。第三种方法,我们首先用一个5x5的高斯核除去噪声,然后再使用Otsu二值化。

代码:

import cv2import numpy as npfrom matplotlib import pyplot as plt img=cv2.imread('C:\\Users\\WLX\\Desktop\\16.png',0)ret1,th1=cv2.threshold(img,127,255,cv2.THRESH_BINARY)ret1,th2=cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_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 Noisy Image','Histogram','Global Thresholding(v=127)','Original Noisy Image','Histogram','Otus s Thresholding','Gaussian giltered Image','Histogram','Otsu s Thresholding']for i in range(3):    plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray')    plt.title(titles[i*3]),plt.xticks([]),plt.yticks([])     plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)    plt.title(titles[i*3+1]),plt.xticks([]),plt.yticks([])    plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')    plt.title(titles[i*3+2]),plt.xticks([]),plt.yticks([])plt.show()
结果:



关于cv2.GassianBlur()这个函数,详情见   点击打开链接 点击打开链接   点击打开链接