目录
一、图像分割
-
图像分割是指将图像分成若干具有相似性质的区域的过程,主要有基于阈值、基于区域、基于边缘、基于聚类、基于图论和基于深度学习的图像分割方法等。
-
图像分割分为
语义分割
和实例分割
。 -
分割的
原则
就是使划分后的子图在内部保持相似度最大,而子图之间的相似度保持最小。 -
将G = (V,E) 分成两个子集A,B,使得:A并B=V,A交B=空集
1、固定阈值图像分割
(1)直方图双峰法-cv2.threshold(src, thresh, maxval, type)
-
双峰法:六十年代中期提出的
直方图双峰法
(也称 mode 法) 是典型的全局单阈值分割方法
。 -
基本思想:假设图像中有明显的目标和背景 ,则其灰度直方图呈双峰分布,当灰度级直方图具有双峰特性时,选取两峰之间的谷对应的灰度级作为阈值。
- 函数:cv2.threshold(src, thresh, maxval, type)
- 参数说明:
参数1:原图像
参数2:对像素值进行分类的阈值
参数3:当像素值高于(小于)阈值时,应该被赋予的新的像素值。
参数4:第四个参数是阈值方法。
返回值:函数有两个返回值,一个为retVal, 一个阈值化处理之后的 图像。
img = cv2.imread('./image/thresh.png', 0)
threshold = 127
ret, th = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# ---------------------------------固定阈值分割---------------------------------
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('./image/person.png', 0)
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)
imges = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
titles = ['img', 'thresh1', 'thresh2', 'thresh3', 'thresh4', 'thresh5']
for i in range(6):
plt.subplot(2, 3, i + 1)
plt.imshow(imges[i], cmap='gray')
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()
2、 自动阈值图像分割
(1)自适应阈值法-cv2.adaptiveThreshold()
-
函数:cv2.adaptiveThreshold()
-
参数说明:
参数1:要处理的原图
参数2:最大阈值,一般为255
参数3:小区域阈值的计算方式
ADAPTIVE_THRESH_MEAN_C:小区域内取均值
ADAPTIVE_THRESH_GAUSSIAN_C:小区域内加权求和,权重是个高斯核
参数4:阈值方式
(跟前面讲的那5种相同)
参数5:小区域的面积
,如11就是11*11的小块
参数6:最终阈值等于小区域计算出的阈值再减去此值 -
特定:自适应阈值会
每次取图片的一小部分计算阈值
,这样图片不同区域的阈值就不尽相同,适用于明暗分布不均的图片。
# 自适应阈值
thresh2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 4)
thresh3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 4)
# ---------------------------------自适应阈值分割---------------------------------
img = cv2.imread('./image/paper2.png', 0)
# 固定阈值
ret, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# 自适应阈值
thresh2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 4)
thresh3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 4)
# 全局阈值,均值自适应,高斯加权自适应对比
titles = ['Original', 'Global(v = 127)', 'Adaptive Mean', 'Adaptive Gaussian']
images = [img, thresh1, thresh2, thresh3]
for i in range(4):
plt.subplot(2, 2, i + 1)
plt.imshow(images[i], cmap='gray')
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()
(3)迭代法阈值分割
- 步骤:
- 求出图象的最大灰度值和最小灰度值,分别记为ZMAX和ZMIN,令初始阈值
T0=(ZMAX+ZMIN)/2
; - 根据阈值TK将图象分割为
前景和背景
,分别求出两者的平均灰度值ZO和ZB
; - 求出
新阈值TK+1=(ZO+ZB)/2
; - 若TK==TK+1,则所得即为阈值;否则转2,
迭代计算
; - 使用计算后的阈值进行固定阈值分割。
(4)Otsu大津法-cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
- 大津法:
•最大类间方差法
,1979年日本学者大津提出,是一种基于全局阈值的自适应方法
。
• 灰度特性:图像分为前景和背
景。当取最佳阈值时,两部分之间的差别应该是最大的,衡量差别的标准为最大类间方差。
• 直方图有两个峰值的图像,大津法求得的T近似等于两个峰值之间的低谷
。
# 固定阈值法
ret1, th1 = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY)
# Otsu阈值法
ret2, th2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 先进行高斯滤波,再Otus
blur = cv2.GaussianBlur(img, (5, 5), 0)
ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# ---------------------------------Otus法---------------------------------
img = cv2.imread('./image/noisy.png', 0)
# 固定阈值法
ret1, th1 = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY)
# Otsu阈值法
ret2, th2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 先进行高斯滤波,再Otus
blur = cv2.GaussianBlur(img, (5, 5), 0)
ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
images = [img, 0, th1, img, 0, th2, blur, 0, th3]
titles = ['Original', 'Histogram', 'Global(v=100)',
'Original', 'Histogram', "Otsu's",
'Gaussian filtered Image', 'Histogram', "Otsu's"]
for i in range(3):
# 绘制原图
plt.subplot(3, 3, i * 3