阈值分割是图像处理中非常实用的操作,对我们提取目标区域,使图像信息更加简单(0和1)来加速后续的处理速度。
图像阈值处理:将高于该值的元素取为0(或者1),将低于该值的元素取值为1(或者0),在OpenCV中,阈值的处理基本操作有下面的几种方式:
1. 简单阈值
cv2.threshold(grayscale_img, th, max_upward, cv::THRESH_BINARY)# 传入灰度图,阈值,大于该阈值取值信息,截断方式,opencv有5中截断方式,最常用的还是cv::THRESH_BINARY和cv::THRESH_BINARY_INV
import numpy as np
import cv2
img=cv2.imread('beauty1.png')
img2gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,imgTh=cv2.threshold(img2gray,127,255,cv2.THRESH_BINARY)#普通阈值
cv2.imshow('img2gray',img2gray)
cv2.imshow('threshold',imgTh)
cv2.waitKey(0)# 一直等待键盘输入
cv2.destroyAllWindows()#关闭显示窗口
thresh简单阈值处理
人像背景是存在灰阶不均匀,阈值处理可以去除部分由于灰阶变化带来的干扰,保留你需要的信息,但同时阈值的选取直接制约着结果的好坏(人像头发细节信息的丢失),尤其是在工业应用当中环境光线的变化导致固定阈值几乎很难同时应对多种场景,涉及图像处理的机器视觉是对光学环境十分依赖的。2. 自适应阈值
th = cv2.adaptiveThreshold(
src, // 输入图像
maxValue, // 向上最大值
adaptiveMethod, // 自适应方法,平均或高斯
thresholdType // 阈值化类型
blockSize, // 块大小 ,须为奇数
C // 常量,阈值会通过计算每个像素周围b x b大小像素块的加权均值并减去常量C得到)
参考博客:图像阈值化
当图像存在灰阶过度的时候,简单阈值往往难以应对,自适应阈值(局部阈值)往往可以实现较好的效果。
import numpy as np
import cv2
img=cv2.imread('beauty1.png')
img2gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#阈值取自邻域的均值
th_mean = cv2.adaptiveThreshold(img2gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 2)
#阈值取值相邻区域的加权和,权重为一个高斯窗口
th_gaussian = cv2.adaptiveThreshold(img2gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 5, 2)
cv2.imshow('adaptive_mean',th_mean)
cv2.imshow('adaptive_gaussian',th_gaussian)
cv2.waitKey(0)
cv2.destroyAllWindows()
当blocksize较小时,阈值能很好的显示图像的边缘纹理特征
adaptive_thresh自适应阈值 这种保留图像边缘特征处理方式在OCR应用(字符识别)中是非常有用的,不过你也会发现这种方法对噪声信号的敏感性,所以往往在之后还会加系列操作来处理噪声。3. OTSU
OTSU是一种对直方图中存在两个主频灰阶峰值图像(目标和背景)效果会最好,这种方法会找出两个主峰之间的灰阶作为阈值。
测试图像的直方图信息如下:
import numpy as np
# 使用matplotlib进行图像绘制
import matplotlib.pyplot as plt
import cv2
img=cv2.imread('beauty1.png')
img2gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 计算直方图信息
hist = cv2.calcHist([img2gray], [0], None, [256], [0, 256])
x = np.arange(0, 256)
# 绘制直方图
# 绘制直方图
plt.plot(x, hist, color = 'k')
plt.fill_between(x, 0, hist[:,0], facecolor='b', alpha=0.3)
plt.show()
直方图信息
两个主要的峰值在50-80之间和150-200之间,使用OTSU方法的阈值效果为:
OTSU自适应阈值
求得的阈值为125,介于主峰之间,能将硬币与背景很好的区分,不过真实的应用场景主要的二主峰图需要特定的光学环境,往往在光学环境调整好后,你使用第一种简单阈值即可解决,不过对于某些光学环境存在一定程度变化的场景,自适应阈值还是很有效的。对于opencv-python的阈值分割,有问题欢迎留言, Have Fun With OpenCV-Python, 下期见。
网友评论