图像的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。
一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。这是研究灰度变换的最特殊的方法,称为图像的二值化(Binarization)。
1. 全局阈(yu)值:
Python-OpenCV中提供了阈值(threshold)函数:cv2.threshold(src, threshold, maxValue, method)
参数解释: 第一个原图像,第二个进行分类的阈值,第三个是高于(低于)阈值时赋予的新值,第四个是一个方法选择参数
src原图:破折线为需要被阈值化的值;虚线为阈值
cv2.THRESH_BINARY:大于阈值的像素点的灰度值设定为maxValue(如8位灰度值最大为255),灰度值小于阈值的像素点的灰度值设定为0。
cv2.THRESH_BINARY_INV :大于阈值的像素点的灰度值设定为0,而小于该阈值的设定为maxValue。
cv2.THRESH_TRUNC:像素点的灰度值小于阈值不改变,大于阈值的灰度值的像素点就设定为该阈值。
cv2.THRESH_TOZERO:像素点的灰度值小于该阈值的不进行任何改变,而大于该阈值的部分,其灰度值全部变为0。
cv2.THRESH_TOZERO_INV:像素点的灰度值大于该阈值的不进行任何改变,像素点的灰度值小于该阈值的,其灰度值全部变为0。
Python+opencv代码:
import cv2 import matplotlib.pyplot as plt img = cv2.imread('C:\Users\Administrator\Desktop\image\22.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret,thresh1 = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) ret,thresh2 = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV) ret,thresh3 = cv2.threshold(gray,127,255,cv2.THRESH_TRUNC) ret,thresh4 = cv2.threshold(gray,127,255,cv2.THRESH_TOZERO) ret,thresh5 = cv2.threshold(gray,127,255,cv2.THRESH_TOZERO_INV) titles = ['img','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()
可以看到这里把阈值设置成了127,对于BINARY方法,当图像中的灰度值大于127的重置像素值为255.
2. 自适应阈值:
前面看到简单阈值是一种全局性的阈值,只需要规定一个阈值值,整个图像都和这个阈值比较。而自适应阈值可以看成一种局部性的阈值,通过规定一个区域大小,比较这个点与区域大小里面像素点的平均值(或者其他特征)的大小关系确定这个像素点是属于黑或者白(如果是二值情况)
Python-OpenCV中提供了阈值(threshold)函数:cv2.adaptiveThreshold(src, maxValue, adaptive_method, threshold_type, block_size, param1)
该函数需要填6个参数:
第一个原始图像
第二个像素值上限
第三个自适应方法Adaptive Method:
— cv2.ADAPTIVE_THRESH_MEAN_C :领域内均值
—cv2.ADAPTIVE_THRESH_GAUSSIAN_C :领域内像素点加权和,权 重为一个高斯窗口
第四个值的赋值方法:只有cv2.THRESH_BINARY 和cv2.THRESH_BINARY_INV
第五个Block size:规定领域大小(一个正方形的领域)
第六个常数C,阈值等于均值或者加权值减去这个常数(为0相当于阈值 就是求得领域内均值或者加权值)
Python+opencv代码:
import cv2 import matplotlib.pyplot as plt img = cv2.imread('C:\Users\Administrator\Desktop\image\ll.jpg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) ret,th1 = cv2.threshold(gray,127,255,cv2.THRESH_BINARY) th2 = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,11,2) #换行符号 th3 = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2) #换行符号 images = [gray,th1,th2,th3] plt.figure() for i in range(4): plt.subplot(2,2,i+1),plt.imshow(images[i],'gray') plt.show()
可以看到上述窗口大小使用的为11,当窗口越小的时候,得到的图像越细。想想一下,如果把窗口设置足够大以后(不能超过图像大小),那么得到的结果可能就和第二幅图像的相同了。