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 相关文章推荐
使用IronPython把Python脚本集成到.NET程序中的教程
Mar 31 Python
Python多线程编程(七):使用Condition实现复杂同步
Apr 05 Python
为Python的web框架编写MVC配置来使其运行的教程
Apr 30 Python
详解Python中 __get__和__getattr__和__getattribute__的区别
Jun 16 Python
DataFrame中的object转换成float的方法
Apr 10 Python
PyCharm代码整体缩进,反向缩进的方法
Jun 25 Python
浅谈django三种缓存模式的使用及注意点
Sep 30 Python
Django实现web端tailf日志文件功能及实例详解
Jul 28 Python
Python爬虫运用正则表达式的方法和优缺点
Aug 25 Python
Python树莓派学习笔记之UDP传输视频帧操作详解
Nov 15 Python
opencv python Canny边缘提取实现过程解析
Feb 03 Python
python操作微信自动发消息的实现(微信聊天机器人)
Jul 14 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代码
2012/07/17 PHP
几道坑人的PHP面试题 试试看看你会不会也中招
2014/08/19 PHP
Zend Framework教程之模型Model用法简单实例
2016/03/04 PHP
如何打开php的gd2库
2017/02/09 PHP
PHPStorm 2020.1 调试 Nodejs的多种方法详解
2020/09/17 NodeJs
jQuery html() in Firefox (uses .innerHTML) ignores DOM changes
2010/03/05 Javascript
基于jquery实现的表格分页实现代码
2011/06/21 Javascript
javascript中的void运算符语法及使用介绍
2013/03/10 Javascript
jquery mobile实现拨打电话功能的几种方法
2013/08/05 Javascript
javascript loadScript异步加载脚本示例讲解
2013/11/14 Javascript
jquery实现点击页面计算点击次数
2015/01/23 Javascript
jquery实现从数组移除指定的值
2015/06/24 Javascript
js密码强度检测
2016/01/07 Javascript
js判断用户是输入的地址请求的路径(实例讲解)
2017/07/18 Javascript
Nginx 配置多站点vhost 的方法
2018/01/07 Javascript
vue 实现边输入边搜索功能的实例讲解
2018/09/16 Javascript
详解用vue2.x版本+adminLTE开源框架搭建后台应用模版
2019/03/15 Javascript
uniapp微信小程序:key失效的解决方法
2021/01/20 Javascript
[02:05]2014DOTA2西雅图邀请赛 专访啸天mik夫妻档
2014/07/08 DOTA
用Python编写一个基于终端的实现翻译的脚本
2015/04/24 Python
python自动翻译实现方法
2016/05/28 Python
python爬虫中get和post方法介绍以及cookie作用
2018/02/08 Python
Python实现的旋转数组功能算法示例
2019/02/23 Python
python代码实现将列表中重复元素之间的内容全部滤除
2020/05/22 Python
CSS3解析抖音LOGO制作的方法步骤
2019/04/11 HTML / CSS
锐步美国官方网站:Reebok美国
2018/01/10 全球购物
包装类的功能、种类、常用方法
2012/01/27 面试题
数组越界问题
2015/10/21 面试题
《草虫的村落》教学反思
2014/02/16 职场文书
保健品市场营销方案
2014/03/31 职场文书
高中生家长寄语大全
2014/04/03 职场文书
学习方法演讲稿
2014/05/10 职场文书
光学与应用专业毕业生求职信
2014/09/01 职场文书
组织生活会表态发言材料
2014/10/17 职场文书
动态规划之使用备忘录来改进Javascript函数
2022/04/07 Javascript
Win11控制面板快捷键是什么?Win11打开控制面板的方法汇总
2022/07/07 数码科技