目录:
- 1.图像二值化
- 2.阈值操作
- 简单阈值(全局阈值)
- 自适应阈值(局部阈值)
- 3.简单阈值 vs 自适应阈值
一、图像二值化
图像二值化:将图像上像素点的灰度值设置为0或255,呈现明显的黑白效果。
图像二值化是图像预处理中必不可少的操作。
OTSU算法(大津法):是一种确定图像二值化分割阈值的算法,由日本学者大津于1979年提出。从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景图像的类间方差最大。
OTSU二值化:
import cv2
# OTSU二值化
img = cv2.imread("image/1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU) # OTSU算法求阈值
cv2.imshow("image", img)
cv2.imshow("gray", gray)
cv2.imshow("binary", binary)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i14479570/4658b24dbdd3412a.png)
二、阈值操作
1.简单阈值
函数:
1)简单阈值操作: threshold()
ret, mask = threshold(src, thresh, maxval, type, dst=None)
ret: thresh阈值
mask: 二值化后的图像
src:图片源
thresh:阈值,取值范围0~255。
maxval:填充色(最大值),取值范围0~255,一般取255。
注意:maxval只对THRESH_BINARY和THRESH_BINARY_INV两种阈值类型有效。
type:阈值类型。常用的几种阈值类型如下:
1)THRESH_BINARY = 0
阈值二值化(threshold binary)
小于等于阈值的像素点置0,大于阈值的像素点置255.
2)THRESH_BINARY_INV = 1
阈值反二值化(threshold binary Inverted)
小于等于阈值的像素点置255,大于阈值的像素点置0.
3)THRESH_TRUNC = 2
截断(truncate)
小于等于阈值的像素点保持原色,大于阈值的像素点置灰(与阈值threshold一致).
4)THRESH_TOZERO = 3
阈值取零(threshold to zero)
小于等于阈值的像素点置0,大于阈值的像素点保持原色。
5)THRESH_TOZERO_INV = 4
阈值反取零(threshold to zero inverted)
小于等于阈值的像素点保持原色,大于阈值的像素点置0。
示例:
import cv2
import matplotlib.pyplot as plt
# 将彩色图转化为灰度图
img = cv2.imread("image/1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 将灰度图转化为二值化图
ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
ret, binary_inv = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
ret, truncate = cv2.threshold(gray, 0, 255, cv2.THRESH_TRUNC | cv2.THRESH_OTSU)
ret, tozero = cv2.threshold(gray, 0, 255, cv2.THRESH_TOZERO | cv2.THRESH_OTSU)
ret, tozero_inv = cv2.threshold(gray, 0, 255, cv2.THRESH_TOZERO_INV | cv2.THRESH_OTSU)
# 结合matplotlib,展示多张二值化图
titles = ['Gray Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [gray, binary, binary_inv, truncate, tozero, tozero_inv]
for i in range(6):
# 划分2行*3列的区域,在第(i+1)个区域上画图
plt.subplot(2, 3, i+1)
# 将图片显示在画板上
# cmap颜色映射: 当img形状是三维矩阵(M,N,3)或(M,N,4)时,值被解释为RGB或RGBA,此时cmap将被忽略。
# 当img形状是二维矩阵(M,N)时,此时cmap用于值到颜色的一个映射。
plt.imshow(images[i], cmap="gray")
# 添加标题
plt.title(titles[i])
# 清空x轴、y轴刻度
plt.xticks([])
plt.yticks([])
plt.show() # 显示画板
![](https://img.haomeiwen.com/i14479570/fe854236206915d3.png)
2.自适应阈值
函数:
2)自适应阈值操作: adaptiveThreshold()
adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)
src:源图片(8位单通道)。
maxval:背景填充色(赋给满足条件的像素的非零值)。
注意:maxval只对THRESH_BINARY和THRESH_BINARY_INV两种阈值类型有效。
adaptiveMethod:自适应阈值的计算方法。两种自适应阈值的计算方法:
1)ADAPTIVE_THRESH_MEAN_C:阈值取自相邻区域的平均值。(平均数-常数)
2)ADAPTIVE_THRESH_GAUSSIAN_C:阈值取自相邻区域的高斯分布加权和。(加权平均数-常数)
thresholdType:阈值类型,只能是THRESH_BINARY或THRESH_BINARY_INV。
blockSize:相相邻区域块大小(用于计算像素点的阈值),且为大于1的奇数(一般取3~11),如: 3,5,7等。
blockSize=11 表示[11 x 11]的一个正方形像素区域块。
C:Constant常数,计算阈值时用平均数或加权平均数减去该常数。一般为正数,也可以是0或负数。
示例:
import cv2
import matplotlib.pyplot as plt
# 读取彩色图片并转化为灰度图
gray = cv2.imread("image/2.jpg", cv2.IMREAD_GRAYSCALE)
# 1.简单阈值(全局阈值)
ret, global_binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# 2.自适应阈值(局部阈值)
adaptive_mean_binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11 ,2)
adaptive_gaussian_binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11 ,2)
titles = ['Gray Image', "Global Thresholding", 'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [gray, global_binary, adaptive_mean_binary, adaptive_gaussian_binary]
for i in range(4):
# 划分[2行*2列]的区域,在第(i+1)个区域上画图
plt.subplot(2, 2, i+1)
# 将图片显示到画板上
plt.imshow(images[i], cmap="gray")
# 添加标题
plt.title(titles[i])
# 清空x轴、y轴坐标刻度
plt.xticks([])
plt.yticks([])
plt.show() # 显示画板
![](https://img.haomeiwen.com/i14479570/e5bfbde1a917b573.png)
三、简单阈值 vs 自适应阈值
简单阈值:即全局固定阈值,整个图像采用同一个阈值。
自适应阈值:即局部阈值,为每个像素点单独计算一个阈值。
一张图片的不同区域具有不同的亮度时,全局阈值往往不能得到想要的效果,这时我们采用自适应阈值。自适应阈值在图像的不同区域采用不同的阈值,从而使我们在图像亮度不同的情况下得到更好的效果。
网友评论