分水岭算法-python-opencv
分水岭算法简单原理:
对于一个图像的灰度值,将图像放平,可以看成是类似与山谷与山顶的图像,灰度值小的就是山底。先找到若干个山底,同时加水,当加到一定程度时候,某些山顶会被淹没,此时在山顶修建大坝,避免两处水汇集在一起。此时这个大坝就是分水岭,即边缘。
原图像:
二值化:
利用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相关推荐
- 分水岭算法java,OpenCV 学习笔记 04 深度估计与分割——GrabCut算法与分水岭算法...
1 使用普通摄像头进行深度估计 1.1 深度估计原理 这里会用到几何学中的极几何(Epipolar Geometry),它属于立体视觉(stereo vision)几何学,立体视觉是计算机视觉的一个分 ...
- 素描滤镜c语言算法,python opencv图像处理(素描、怀旧、光照、流年、滤镜 原理及实现).pdf...
python opencv 图图像像处处理理(素素描描..怀怀旧旧..光光照照..流流年年..滤滤镜镜 原原理理及及实实现现) 这篇文章主要介绍了python 基于opencv对图像进行各种处理,帮助 ...
- OpenCV学习(二十) :分水岭算法:watershed()
OpenCV学习(二十) :分水岭算法:watershed() 参考博客: OpenCV-分水岭算法 图像处理--分水岭算法 OpenCV学习(7) 分水岭算法(1) Opencv分水岭算法--wat ...
- 使用OpenCV的分水岭算法
<使用OpenCV的分水岭算法> 之前利用watershed想对相对前背景较为明显的图像进行图像语义分割的预打标,因为虽然前景明显,但是边缘打标也是很困难的,可以用该方法对大部分的边缘 ...
- 【OpenCV】 - 图像分割之分水岭算法,watershed()函数的输出,对marker和image的改变
一.背景 最近在学分水岭算法的opencv函数watershed()时,对函数执行完后image和marker的变化一无所知.懵懵懂懂. 于是便结合网上资料和自己现身说法,给大家分享一下[waters ...
- 目标分割算法之分水岭算法
分水岭算法 1.经典算法原理及实现 传统的目标分割算法主要分为两种 1.基于像素相似性:阈值分割.k-means分割 2.基于像素邻域关系:区域生长.分水岭.基于标记+分水岭 分水岭算法原理 如图中展 ...
- Python+OpenCV:基于分水岭算法的图像分割(Image Segmentation with Watershed Algorithm)
Python+OpenCV:基于分水岭算法的图像分割(Image Segmentation with Watershed Algorithm) ############################ ...
- Python+Opencv分水岭算法
目录 一.分水岭算法(Watershed)简介 二.分水岭算法实现步骤 三.阈值和轮廓检测硬币分割代码实现与分析 四.分水岭硬币分割代码实现 五.代码效果展示与分析 参考资料 注意事项 一.分水岭算法 ...
- 【python】【openCV】分水岭算法
脑血管医学图像颅内分割尝试--分水岭算法 code 1.2 不分割颅内直接分割 code 2.0 实验版 code 3.0 批量处理版 code 3.1 加入孔洞填充 总结 本篇博客原目的同https ...
- opencv python 基于分水岭算法的图像分割
Image Segmentation with Watershed Algorithm 理论 任何灰度图像都可以看作是地形表面,其中高强度表示山峰和丘陵,而低强度表示山谷.用不同颜色的水(标签)填充每 ...
最新文章
- 作为一个新人,如何学习嵌入式Linux?
- MySQL主从同步(复制)
- 通过反射动态调用webservices
- Oracle清除缓存的命令,Oracle的get命令
- eclipse和myeclipse中如何关闭自动补全括号,花括号,双引号等功能
- Linux非系统盘挂载,[转载] Linux mount 挂载分区、硬盘
- android数据库开发案例教程,Android Studio项目开发教程 第6章 数据库编程(30页)-原创力文档...
- 70多个国家地区免费享受wifi
- Kubernetes: 集群网络配置 - flannel
- 关于WindowsPE的DIY和黑科技
- php 从1累加到50,javascript - 一个数每隔一秒执行加1并打印出来,一直加到50停止,用js如何实现?...
- js页面跳转,参数传递
- 东北大学22春学期《概率论X》在线平时作业123
- 联想S41-70笔记本拆机换内存条图解——小白进阶之路
- 爬虫入门(五):下载豆瓣电影信息
- Linux 修改 host
- Python selenium —— 一定要会用selenium的等待,三种等待方式解读
- 山科计算机科学与技术学院,山东科技大学-计算机科学与工程学院
- Java基础知识学完了,还在看着控制台上输出的结果发呆吗?还不来认识认识GUI编程(初识GUI)
- 改变PPT导出图片分辨率