目标
阈值化 === 二值化
• 本节你将学到简单阈值,自适应阈值,Otsu’s 二值化等
• 将要学习的函数有 cv2.threshold,cv2.adaptiveThreshold 等。
图像二值化函数cv2.threshold函数的介绍。
图像的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果(灰度值0:黑,灰度值255:白).
在图像中除了目标物体和背景区域,还有噪声,这都会对于我们对图像的识别造成困扰,所以我们要通过图像二值化函数将多值的数字图像中直接提取出目标图像,也就是说设定一个阈值T,用T将图像的象素群一分为二。
图像二值化:就是将图像上的像素点设置为0或者255也就是将整个图像呈现为明显的黑白效果.二值化使图像的数据量大为减少,从而凸显出目标的轮廓.
图像阈值化处理就是利用图像像素点的分布规律,设定阈值进行像素点分割,进而得到图像的二值图像.因为二值图每个像素只有两个值,所以每个像素只需要1bit即可存储。
分类
- 全局阈值化:在光照不均匀的条件下难以引用
- 简单阈值化:
cv2.threshold()
- OSTU阈值化:计算机自己选择阈值
- 简单阈值化:
- 局部阈值化:针对图像的不同部分采用不同的阈值来解决光照问题,其阈值实际上是一个随图像变化的曲面
- 自适应阈值化
二值图像 VS 灰度图像
- 二值图像是指每个像素不是黑,就是白,其灰度值没有中间过渡的图像,这种图像又称为黑白图像。二值图像的每一个像素只有两个值0和1,其中0表示黑色,1表示白色,所以二值图都是长这样的。
- 灰度图是在二值图像的基础上使用8bit来存储每一个像素的值,所以其范围在0~255之间,因此标准灰度图像中每个像素的灰度值是0-255之间的1个值,灰度级数为256级,因此不同于二值图像,灰度图像的颜色信息更加丰富,不仅仅只有白色和黑色,还有各种灰色,共有256个灰度值。
15.1 全局阈值化-简单阈值
这个函数就是 cv2.threshhold(src,thresh,maxval,type,dst=None)。
- src:原图像,原图像应该是
灰度图
。 - thresh:就是用来对像素值进行分类的阈值。
- maxval:就是当像素值高于(有时是小于)阈值时应该被赋予的新的像素值。
- 提供了多种不同的阈值方法,如何赋新值
• cv2.THRESH_BINARY 二进制阈值化,大于thresh设为max反之为0
• cv2.THRESH_BINARY_INV 反二进制阈值化
• cv2.THRESH_TRUNC 截断阈值化 大于thresh设为thresh反之不变
• cv2.THRESH_TOZERO 阈值化为0 大于thresh的不变反之为0
• cv2.THRESH_TOZERO_INV 反阈值化为0 - 返回值:
- 这个函数有两个返回值,第一个为 retVal,设定的阈值。第二个就是阈值化之后的结果图像了。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('./Pytorch.png',flags=cv2.IMREAD_GRAYSCALE)
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 = ['Original 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()
一般适用于场景单一,固定的场合,例如工业车间
15.2 全局阈值化-OTSU 二值化
- 简单来说就是对一副双峰图像自动根据其直方图计算出一个阈值。(对于非双峰图像,这种方法得到的结果可能会不理想)。
适用于灰度直方图有两个峰值的图像
. - 这个最优阈值就是返回值 retVal。如果不使用 Otsu 二值化,返回
retVal 值与设定的阈值相等(上面的两个阈值方法就是)。 - cv2.threshhold(src,0,255,THRESH_BINARY+cv.THRESH_OTSU)
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('noise.png',0)
# global thresholding
ret1,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
# Otsu's thresholding
ret2,th2 = cv.threshold(img,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
# Otsu's thresholding after Gaussian filtering
blur = cv.GaussianBlur(img,(5,5),0)
ret3,th3 = cv.threshold(blur,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)
# plot all the images and their histograms
images = [img, 0, th1,
img, 0, th2,
blur, 0, th3]
titles = ['Original Noisy Image','Histogram','Global Thresholding (v=127)',
'Original Noisy Image','Histogram',"Otsu's Thresholding",
'Gaussian filtered 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()
15.3 局部阈值化-自适应阈值
- 阈值是根据图像上的每一个小区域计算与其对应的阈值。因此在同一幅图像上的不同区域采用的是不同的阈值,从而使我们能在亮度不同的情况下得到更好的结果.
使用于亮度不均匀条件下
cv2.adaptiveThreshold(src,maxvalue,adaptiveMethod,threshholdType,blocksize,C,dst=None)
-
src:
灰度图
-
maxValue:预设满足条件的最大值
-
Adaptive Method
- 指定计算阈值的方法。- cv2.ADPTIVE_THRESH_MEAN_C:阈值取自相邻区域的平
均值 - cv2.ADPTIVE_THRESH_GAUSSIAN_C:阈值取值相邻区域
的加权和,权重为一个高斯窗口。
- cv2.ADPTIVE_THRESH_MEAN_C:阈值取自相邻区域的平
-
threshholdType:统简单阈值化的type
-
Block Size - 邻域大小(用来计算阈值的区域大小):3,5,7
-
C - 这就是是一个常数,阈值就等于的平均值或者加权平均值减去这个常.
可以通过添加滑动条来选择最好的效果
数。可以是负数
-
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('Pytorch.png',cv2.IMREAD_GRAYSCALE)
# 中值滤波
img = cv2.medianBlur(img,5)
ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
#11 为 Block size, 2 为 C 值
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()