【深度之眼opencv-5】:图像分割(阈值分割、边缘检测、连通、区域生长、分水岭)

一、图像分割

  • 图像分割是指将图像分成若干具有相似性质的区域的过程,主要有基于阈值、基于区域、基于边缘、基于聚类、基于图论和基于深度学习的图像分割方法等。

  • 图像分割分为语义分割实例分割

  • 分割的原则就是使划分后的子图在内部保持相似度最大,而子图之间的相似度保持最小。

  • 将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)迭代法阈值分割

  • 步骤:
  1. 求出图象的最大灰度值和最小灰度值,分别记为ZMAX和ZMIN,令初始阈值 T0=(ZMAX+ZMIN)/2;
  2. 根据阈值TK将图象分割为前景和背景,分别求出两者的平均灰度值ZO和ZB ;
  3. 求出新阈值TK+1=(ZO+ZB)/2;
  4. 若TK==TK+1,则所得即为阈值;否则转2,迭代计算;
  5. 使用计算后的阈值进行固定阈值分割。

(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 + 
  • 14
    点赞
  • 113
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值