python opencv之分水岭算法示例


Posted in Python onFebruary 24, 2018

本文介绍了python opencv之分水岭算法示例,分享给大家,具体如下:

目标

  1. 使用分水岭算法对基于标记的图像进行分割
  2. 使用函数cv2.watershed()

原理:

灰度图像可以被看成拓扑平面,灰度值高的区域可以看出山峰,灰度值低的区域可以看成是山谷。向每一个山谷当中灌不同颜色的水。水位升高,不同山谷的水会汇合,为防止不同山谷的水汇合,小在汇合处建立起堤坝。然后继续灌水,然后再建立堤坝,直到山峰都掩模。构建好的堤坝就是图像的分割。

此方法通常会得到过渡分割的结果,因为图像中的噪声以及其他因素。为了减少此影响,opencv使用基于标记的分水岭算法,此算法要设置哪些山谷中的汇合点,哪些不是。这是一种交互式的图像分割算法那。我们要给已知对象打上不同表情。如果某个区域肯定是前景或对象,就使用某个颜色或灰度值标签标记它。如果是背景那么使用其他颜色进行标记,其余不能确定的部分用0标记。然后使用分水岭算法,每次灌水,标签会被更新,当两个不同颜色的标签相遇就会构建堤坝,知道所有山峰掩模,最后得到的边界对象值是-1。

代码:

对挨在一起的对象进行分割。

python opencv之分水岭算法示例

使用Otsu's 二值化后的结果为

python opencv之分水岭算法示例

要出去图像中的白噪声。可以使用形态学运算,使用闭运算去除对象中的空洞。

靠近对象中心的区域是前景,离对象远的区域是背景,不确定的区域是边界。

首先提取硬币区域,使用腐蚀操作去掉边缘,剩下的就是硬币。但硬币没有接触时,此方法有效,但是由于硬币相互接触,就要使用另外一种有效的方法:距离变换加上合适的阈值。

之后,要寻找不确定是否是硬币的区域。这里需要膨胀操作。膨胀操作会将对象边界延伸到背景当中。由于边界区域被去除,现在就能知道哪些区域是前景,哪些是背景。

余下的区域不知道如何区分,那么使用分水岭算法。这些区域通常是前景与背景的交界处。从能否确认是否是背景的区域中减去确定是前景的区域就得到了边界。

(前景和背景)

python opencv之分水岭算法示例

(上面的图是直接使用作者的代码后生产的结果,提取到了前景,为了演示一下不确定的区域,调了一下计算前景的距离变换的参数,使得中间出现不确定的区域)

python opencv之分水岭算法示例

这里面使用个cv2.distanceTransform函数

该函数用于计算2值图象中所有像素离其最近的值为0像素的近似距离。

参数为

cv2.distanceTransform(src, distanceType, maskSize[, dst]) → dst

#src为输入的二值图像。distanceType为计算距离的方式,可以是如下值
DIST_USER = ⑴, //!< User defined distance
DIST_L1  = 1, //!< distance = |x1-x2| + |y1-y2|
DIST_L2  = 2, //!< the simple euclidean distance
DIST_C  = 3, //!< distance = max(|x1-x2|,|y1-y2|)
DIST_L12  = 4, //!< L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1))
DIST_FAIR = 5, //!< distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998
DIST_WELSCH = 6, //!< distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846
DIST_HUBER = 7 //!< distance = |x|<c ? x^2/2 : c(|x|-c/2), c=1.345


#maskSize是蒙板尺寸,只有0,3,5
DIST_MASK_3  = 3, //!< mask=3
DIST_MASK_5  = 5, //!< mask=5
DIST_MASK_PRECISE = 0 //!< mask=0
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('21.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)
# sure background area
sure_bg = cv2.dilate(opening,kernel,iterations=3)#膨胀
# Finding sure foreground area

dist_transform = cv2.distanceTransform(opening,1,5)
ret, sure_fg = cv2.threshold(dist_transform,0.2*dist_transform.max(),255,0)#参数改小了,出现不确定区域
# Finding unknown region
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg,sure_fg)#减去前景

cv2.imshow('p',sure_fg)
cv2.waitKey(0)

现在知道了那些背景是硬币,可以创建标签。(与原图像大小相同,数据类型为int32的数组)。

对于已经确定分类的区域,也就是背景和前景,使用整数标记,不确定的区域是用0标记。可以使用cv2.connectedComponents()函数来实现此功能。它会将背景标记为0,其他标记为位从1开始的正整数。

但是,如果背景标记为0,那么分水岭算法会将其当成位置区域,所以使用不同的整数进行标记,对于不确定的区域,函数标记为0.

结果使用JET颜色地图表示。深蓝色未知区域,硬币区域使用不同颜色。其余部分用浅蓝色。

使用分水岭算法

效果不错

python opencv之分水岭算法示例

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python两种遍历字典(dict)的方法比较
May 29 Python
python使用pyhook监控键盘并实现切换歌曲的功能
Jul 18 Python
pygame学习笔记(5):游戏精灵
Apr 15 Python
浅谈python socket函数中,send与sendall的区别与使用方法
May 09 Python
python生成词云的实现方法(推荐)
Jun 13 Python
Python数据结构之图的应用示例
May 11 Python
Python3.6.2调用ffmpeg的方法
Jan 10 Python
python实现字符串加密成纯数字
Mar 19 Python
在 Jupyter 中重新导入特定的 Python 文件(场景分析)
Oct 27 Python
Python面向对象封装操作案例详解
Dec 31 Python
python GUI库图形界面开发之PyQt5选项卡控件QTabWidget详细使用方法与实例
Mar 01 Python
Python实战之疫苗研发情况可视化
May 18 Python
python3爬取各类天气信息
Feb 24 #Python
python opencv之SIFT算法示例
Feb 24 #Python
python3 破解 geetest(极验)的滑块验证码功能
Feb 24 #Python
python opencv之SURF算法示例
Feb 24 #Python
几种实用的pythonic语法实例代码
Feb 24 #Python
使用Python爬取最好大学网大学排名
Feb 24 #Python
python opencv 直方图反向投影的方法
Feb 24 #Python
You might like
php支付宝接口用法分析
2015/01/04 PHP
php实现购物车功能(上)
2020/07/23 PHP
php中的explode()函数实例介绍
2019/01/18 PHP
一款JavaScript压缩工具:X2JSCompactor
2007/06/13 Javascript
UserData用法总结 lanyu出品
2010/07/01 Javascript
项目中常用的JS方法整理
2015/01/30 Javascript
JS实现往下不断流动网页背景的方法
2015/02/27 Javascript
基于JavaScript实现百叶窗动画效果不只单纯flas可以实现
2016/02/29 Javascript
Javascript单例模式的介绍和实例
2016/10/08 Javascript
JS实现的简单表单验证功能示例
2017/10/13 Javascript
angularjs select 赋值 ng-options配置方法
2018/02/28 Javascript
Angular 5.x 学习笔记之Router(路由)应用
2018/04/08 Javascript
r.js来合并压缩css文件的示例
2018/04/26 Javascript
一个Vue视频媒体多段裁剪组件的实现示例
2018/08/09 Javascript
Vue前后端不同端口的实现方法
2018/09/19 Javascript
webpack4之如何编写loader的方法步骤
2019/06/06 Javascript
Vue 实现一个命令式弹窗组件功能
2019/09/25 Javascript
微信小程序使用 vant Dialog组件的正确方式
2020/02/21 Javascript
在Python3中使用asyncio库进行快速数据抓取的教程
2015/04/02 Python
python获取指定网页上所有超链接的方法
2015/04/04 Python
python利用sklearn包编写决策树源代码
2017/12/21 Python
JavaScript实现一维数组转化为二维数组
2018/04/17 Python
python 去除txt文本中的空格、数字、特定字母等方法
2018/07/24 Python
django创建超级用户过程解析
2019/09/18 Python
Python+OpenCV实现旋转文本校正方式
2020/01/09 Python
python对一个数向上取整的实例方法
2020/06/18 Python
python 实现波浪滤镜特效
2020/12/02 Python
input file上传文件样式支持html5的浏览器解决方案
2012/11/14 HTML / CSS
德国网上宠物店:Zoobio
2018/05/23 全球购物
介绍一下Linux中的链接
2016/05/28 面试题
自荐信的禁忌和要点
2013/10/15 职场文书
职业技术学校毕业生推荐信
2013/12/03 职场文书
学生会招新策划书
2014/02/14 职场文书
2015年感恩节演讲稿(优选篇)
2015/03/20 职场文书
2019幼儿园感恩节活动策划书
2019/11/28 职场文书
使用Java去实现超市会员管理系统
2022/03/18 Java/Android