OpenCV-图像处理(33、基于距离变换与分水岭的图像分割)

什么是图像分割(Image Segmentation)

  • 图像分割(Image Segmentation)是图像处理最重要的处理手段之一

  • 图像分割的目标是将图像中像素根据一定的规则分为若干(N)个cluster集合,每个集合包含一类像素。

  • 根据算法分为监督学习方法和无监督学习方法,图像分割的算法多数都是无监督学习方法 - KMeans

  • 从数学角度来看,图像分割是将数字图像划分成互不相交的区域的过程。图像分割的过程也是一个标记过程,即把属于同一区域的像索赋予相同的编号。目的是将图像中像素根据一定的规则分为若干(N)个聚(cluster)集合,每个集合包含一类像素。将对象在背景提取出来。
    在这里插入图片描述

距离变换与分水岭介绍

可以参考:https://blog.csdn.net/zhangjunp3/article/details/79672098

  • 在这里插入图片描述

  • 在这里插入图片描述

  • 在这里插入图片描述

距离变换常见算法有两种:
  • 不断膨胀/ 腐蚀得到
  • 基于倒角距离
分水岭变换常见的算法
  • 基于浸泡理论实现

可以参考:https://blog.csdn.net/zhu_hongji/article/details/81703350

相关API

  • (1)距离变换:计算源图像的每个像素到最近的零像素的距离.
    distanceTransform(
    InputArray src, //8位单通道(二进制)源图像
    OutputArray dst, //输出具有计算距离的图像,8位或32位浮点的单通道图像,大小与src相同.
    OutputArray labels, //输出二维数组标签labels(离散维诺Voronoi图),类型为 CV_32SC1 ,相同距离的算做同一个 label ,算出总共由多少个 labels
    int distanceType, //距离类型 = DIST_L1/DIST_L2
    int maskSize, //距离变换的掩膜大小,DIST_MASK_3(maskSize = 3x3),最新的支持DIST_MASK_5(mask = 5x5),//最新的支持5x5,推荐3x3、
    int labelType=DIST_LABEL_CCOMP //要生成的标签数组的类型
    )

    参数四距离可选类型:
    在这里插入图片描述
    参数六标签可选类型:在这里插入图片描述
  • (2)分水岭:用分水岭算法执行基于标记的图像分割
    watershed(
    InputArray image, //输入8位3通道图像(输入锐化原图8位3通道)
    InputOutputArray markers // 输入或输出32位单通道的标记,和图像一样大小。(输入高峰轮廓标记)
    )

处理流程

  1. 将白色背景变成黑色-目的是为后面的变换做准备
  2. 使用filter2D与拉普拉斯算子实现图像对比度提高,sharp
  3. 转为二值图像通过threshold
  4. 距离变换
  5. 对距离变换结果进行归一化到[0~1]之间
  6. 使用阈值,再次二值化,得到标记
  7. 腐蚀得到每个Peak - erode
  8. 发现轮廓 – findContours
  9. 绘制轮廓- drawContours
  10. 分水岭变换 watershed
  11. 对每个分割区域着色输出结果

演示代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

程序代码

可以参考:https://blog.csdn.net/huanghuangjin/article/details/81194552

运行截图

参考博客

  1. https://blog.csdn.net/zhangjunp3/article/details/79672098
  2. https://blog.csdn.net/zhu_hongji/article/details/81703350
  3. https://blog.csdn.net/iracer/article/details/49225823
  4. https://blog.csdn.net/huanghuangjin/article/details/81194552
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
基于分水岭算法的图像分割是一种常用的图像处理技术,可以将图像分割成多个区域,每个区域内的像素具有相似的特征。在 OpenCV 中,可以使用 cv2.watershed() 函数实现基于分水岭算法的图像分割。 下面是一个简单的 Python 示例,演示如何使用基于分水岭算法的图像分割: ```python import cv2 import numpy as np # 读取图像 img = cv2.imread('image.jpg') # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 阈值分割 ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) # 形态学操作 kernel = np.ones((3,3),np.uint8) opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel,iterations=2) # 距离变换 dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5) ret, sure_fg = cv2.threshold(dist_transform,0.1*dist_transform.max(),255,0) # 背景区域 sure_bg = cv2.dilate(opening,kernel,iterations=3) # 不确定区域 sure_fg = np.uint8(sure_fg) unknown = cv2.subtract(sure_bg,sure_fg) # 标记连通区域 ret, markers = cv2.connectedComponents(sure_fg) markers = markers + 1 markers[unknown==255] = 0 # 应用分水岭算法 markers = cv2.watershed(img,markers) img[markers == -1] = [255,0,0] # 显示结果 cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上面的示例中,首先读取一张图像,并将其转换为灰度图像。然后使用阈值分割算法将图像二值化。接下来,进行形态学操作,以去除图像中的噪声。然后使用距离变换算法计算前景区域,并将其阈值化。接着,使用形态学操作计算背景区域。最后,使用 cv2.connectedComponents() 函数计算不确定区域,并使用标记连通区域的方法生成分水岭算法的输入标记图像。最后,应用 cv2.watershed() 函数进行图像分割,并在窗口中显示结果。 需要注意的是,分水岭算法的结果依赖于输入标记图像的质量,因此需要根据具体情况进行调整,比如阈值分割的参数、形态学操作的参数、距离变换的参数等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值