分水岭算法简单原理:

对于一个图像的灰度值,将图像放平,可以看成是类似与山谷与山顶的图像,灰度值小的就是山底。先找到若干个山底,同时加水,当加到一定程度时候,某些山顶会被淹没,此时在山顶修建大坝,避免两处水汇集在一起。此时这个大坝就是分水岭,即边缘。

原图像:

二值化:

利用OTSU方法首先进行二值化操作:

详情请看:图像阈值处理-OpenCV_独憩的博客-CSDN博客

import cv2.cv2
import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltimg = cv.imread(r'XXXXX\water_coins.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV+cv.THRESH_OTSU)

形态学得到边界区域:

对于分水岭算法,我们首先要得到边界可能存在的区域,你们对于上述图像来说,我们要得到的图像为”圆环“

开始直接我们采用开运算去除噪声;

故我们先需要得到一些确定的”背景“,和一些确定的”内部“,利用两者相减得到边界可能存在的区域,即圆环;

确定的”背景“可以使原二值图像”膨胀“得到,确定的”内部“可以使原二值图像”腐蚀“得到,具体原理见:图像膨胀、腐蚀、开运算、闭运算---python.opencv_独憩的博客-CSDN博客

kernel = np.ones((3,3),np.uint8)
#去除噪声
opening = cv.morphologyEx(thresh,cv.MORPH_OPEN,kernel, iterations = 3)
#膨胀得到背景
sure_bg = cv.dilate(opening,kernel,iterations=3)
#腐蚀得到前景
sure_fg = cv2.erode(opening, kernel, iterations=3)
sure_fg = np.uint8(sure_fg)
#两者相减得到边缘可能存在区域
unknown = cv.subtract(sure_bg,sure_fg)plt.figure()
plt.subplot(1,3,1)
plt.imshow(sure_bg,'gray')
plt.title('sure background area')
plt.xticks([]),plt.yticks([])
plt.subplot(1,3,2)
plt.imshow(sure_fg,'gray')
plt.title('sure foreground area')
plt.xticks([]),plt.yticks([])
plt.subplot(1,3,3)
plt.imshow(unknown,'gray')
plt.title('unknown')
plt.xticks([]),plt.yticks([])
plt.show()


但是从图像看出,unknown图像中由于硬币重叠,有部分边界被抵消,故我们采用另外一种方法:

首先介绍一个函数:

dist_transform = cv.distanceTransform(opening,cv.DIST_L2,5)

我们只需要知道,这个函数的作用是得到图像(灰度)中所有非零像素与最近的零像素的距离

我们可以通过对dist_transform图像进行阈值处理得到确定的”内部“,这样的好处是可以控制圆环的粗细,阈值处理 cv.threshold具体见:图像阈值处理-OpenCV_独憩的博客-CSDN博客

kernel = np.ones((3,3),np.uint8)
opening = cv.morphologyEx(thresh,cv.MORPH_OPEN,kernel, iterations = 3)sure_bg = cv.dilate(opening,kernel,iterations=3)dist_transform = cv.distanceTransform(opening,cv.DIST_L2,5)
ret, sure_fg = cv.threshold(dist_transform,0.5*dist_transform.max(),255,0)
sure_fg = np.uint8(sure_fg)
unknown = cv.subtract(sure_bg,sure_fg)plt.figure()
plt.subplot(1,3,1)
plt.imshow(sure_bg,'gray')
plt.title('sure background area')
plt.xticks([]),plt.yticks([])
plt.subplot(1,3,2)
plt.imshow(sure_fg,'gray')
plt.title('sure foreground area')
plt.xticks([]),plt.yticks([])
plt.subplot(1,3,3)
plt.imshow(unknown,'gray')
plt.title('unknown')
plt.xticks([]),plt.yticks([])
plt.show()

背景,前景,边界区域分类:

然后我们需要对背景,前景(内部),边界区域进行分类:

ret, markers = cv2.connectedComponents(sure_fg)markers = markers+1 #使得背景为1markers[unknown==255] = 0  #使得边界区域为0
markers_copy = markers.copy()markers_copy[markers==0] = 150  # 灰色表示背景
markers_copy[markers==1] = 0    # 黑色表示背景
markers_copy[markers>1] = 255   # 白色表示前景markers_copy = np.uint8(markers_copy)
plt.figure()
plt.imshow(markers_copy,'gray')
plt.title('markers')
plt.xticks([]),plt.yticks([])
plt.show()

cv2.watershed():

最后直接调用分水岭算法函数:

markers = cv2.watershed(img, markers)
img=cv.cvtColor(img,cv.COLOR_BGR2RGB)
img[markers==-1] = [255,0,0]
plt.figure()
plt.imshow(img,'gray')plt.xticks([]),plt.yticks([])
plt.show()

分水岭算法-python-opencv相关推荐

  1. 分水岭算法java,OpenCV 学习笔记 04 深度估计与分割——GrabCut算法与分水岭算法...

    1 使用普通摄像头进行深度估计 1.1 深度估计原理 这里会用到几何学中的极几何(Epipolar Geometry),它属于立体视觉(stereo vision)几何学,立体视觉是计算机视觉的一个分 ...

  2. 素描滤镜c语言算法,python opencv图像处理(素描、怀旧、光照、流年、滤镜 原理及实现).pdf...

    python opencv 图图像像处处理理(素素描描..怀怀旧旧..光光照照..流流年年..滤滤镜镜 原原理理及及实实现现) 这篇文章主要介绍了python 基于opencv对图像进行各种处理,帮助 ...

  3. OpenCV学习(二十) :分水岭算法:watershed()

    OpenCV学习(二十) :分水岭算法:watershed() 参考博客: OpenCV-分水岭算法 图像处理--分水岭算法 OpenCV学习(7) 分水岭算法(1) Opencv分水岭算法--wat ...

  4. 使用OpenCV的分水岭算法

    <使用OpenCV的分水岭算法>   之前利用watershed想对相对前背景较为明显的图像进行图像语义分割的预打标,因为虽然前景明显,但是边缘打标也是很困难的,可以用该方法对大部分的边缘 ...

  5. 【OpenCV】 - 图像分割之分水岭算法,watershed()函数的输出,对marker和image的改变

    一.背景 最近在学分水岭算法的opencv函数watershed()时,对函数执行完后image和marker的变化一无所知.懵懵懂懂. 于是便结合网上资料和自己现身说法,给大家分享一下[waters ...

  6. 目标分割算法之分水岭算法

    分水岭算法 1.经典算法原理及实现 传统的目标分割算法主要分为两种 1.基于像素相似性:阈值分割.k-means分割 2.基于像素邻域关系:区域生长.分水岭.基于标记+分水岭 分水岭算法原理 如图中展 ...

  7. Python+OpenCV:基于分水岭算法的图像分割(Image Segmentation with Watershed Algorithm)

    Python+OpenCV:基于分水岭算法的图像分割(Image Segmentation with Watershed Algorithm) ############################ ...

  8. Python+Opencv分水岭算法

    目录 一.分水岭算法(Watershed)简介 二.分水岭算法实现步骤 三.阈值和轮廓检测硬币分割代码实现与分析 四.分水岭硬币分割代码实现 五.代码效果展示与分析 参考资料 注意事项 一.分水岭算法 ...

  9. 【python】【openCV】分水岭算法

    脑血管医学图像颅内分割尝试--分水岭算法 code 1.2 不分割颅内直接分割 code 2.0 实验版 code 3.0 批量处理版 code 3.1 加入孔洞填充 总结 本篇博客原目的同https ...

  10. opencv python 基于分水岭算法的图像分割

    Image Segmentation with Watershed Algorithm 理论 任何灰度图像都可以看作是地形表面,其中高强度表示山峰和丘陵,而低强度表示山谷.用不同颜色的水(标签)填充每 ...

最新文章

  1. 作为一个新人,如何学习嵌入式Linux?
  2. MySQL主从同步(复制)
  3. 通过反射动态调用webservices
  4. Oracle清除缓存的命令,Oracle的get命令
  5. eclipse和myeclipse中如何关闭自动补全括号,花括号,双引号等功能
  6. Linux非系统盘挂载,[转载] Linux mount 挂载分区、硬盘
  7. android数据库开发案例教程,Android Studio项目开发教程 第6章 数据库编程(30页)-原创力文档...
  8. 70多个国家地区免费享受wifi
  9. Kubernetes: 集群网络配置 - flannel
  10. 关于WindowsPE的DIY和黑科技
  11. php 从1累加到50,javascript - 一个数每隔一秒执行加1并打印出来,一直加到50停止,用js如何实现?...
  12. js页面跳转,参数传递
  13. 东北大学22春学期《概率论X》在线平时作业123
  14. 联想S41-70笔记本拆机换内存条图解——小白进阶之路
  15. 爬虫入门(五):下载豆瓣电影信息
  16. Linux 修改 host
  17. Python selenium —— 一定要会用selenium的等待,三种等待方式解读
  18. 山科计算机科学与技术学院,山东科技大学-计算机科学与工程学院
  19. Java基础知识学完了,还在看着控制台上输出的结果发呆吗?还不来认识认识GUI编程(初识GUI)
  20. 改变PPT导出图片分辨率

热门文章

  1. 一夜暴涨12%市值突破7000亿美元,英伟达为何上演大涨神话?
  2. Git的提交说明规范
  3. 数字图像处理知识体系小结(转)
  4. 水质评价---2综合水质标识指数法
  5. 《程序员的自我修养》第3章---目标文件里有什么
  6. Linux 从懵懂到玩得很溜
  7. (一)VMware搭建华为FusionCompute6.5.1,可正常使用 —— 搭建KVM虚拟化基础环境
  8. linux2019/8/1
  9. 基于AX7020的petalinux生成并驱动液晶屏(071)
  10. python爬虫学习笔记-SQL学习