OpenCV-Python系列三:图像分割(1)--阈值
2020-06-11 本文已影响0人
CodeFUN
阈值分割是图像处理中非常实用的操作,对我们提取目标区域,使图像信息更加简单(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()#关闭显示窗口

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较小时,阈值能很好的显示图像的边缘纹理特征

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()


对于opencv-python的阈值分割,有问题欢迎留言, Have Fun With OpenCV-Python, 下期见。