OpenCV分水岭watershed的应用注意
来源:互联网 发布:python 提取文件路径 编辑:程序博客网 时间:2024/06/05 19:15
在VS2010,OpenCV进行分水岭的实现时。我遇到了一个问题:
在做好种子图和背景图后,也无法分隔开同一个背景框内的多个种子点。网上给的方法都是将背景点设置为灰度128,种子点设置为255,其他为0。然后前景背景叠加作为mark图。再调用watershed(原图,蒙版)。
但是,按照这个结果做出来的话,同一个128灰度的区域包围的多个255灰度的种子区域无法被区分开。通过阅读OpenCV源码,我发现了原因。
/*-----划分:如果其4邻域只有一个集水区那就归入其中,如果有多个那就标记为分水岭------*/ if( q[active_queue].first == 0 ) //当前层级处理完或无像素入队,换下一层 { for( i = active_queue+1; i < NQ; i++ ) if( q[i].first ) //换这层 break; if( i == NQ ) //退出大循环 break; active_queue = i; //下面给这一层的像素分配标号 } //取一个点 ws_pop( active_queue, mofs, iofs ); m = mask + mofs; //mask的值 ptr = img + iofs; //img的值 //4邻域只有一个区域,确定区域归属,要是处在多个集水区,成为分水岭 t = m[-1]; if( t > 0 ) lab = t; t = m[1]; if( t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } t = m[-mstep]; if( t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } t = m[mstep]; if( t > 0 ) { if( lab == 0 ) lab = t; else if( t != lab ) lab = WSHED; } assert( lab != 0 ); m[0] = lab; if( lab == WSHED ) continue; //继续
在这一部分可以看出,在设置分水岭位置时,是通过比较上下左右四个点,是否有不为0且不同的两个灰度点,如果有,那么设置为WSHED(-1),也就是分水岭位置。
引用一个比较易懂专业的描述:如果mask图像中该像素的四邻域中存在两个不同的非0值,表示该点为两个注水盆地的边缘,即分水岭线,在mark图像中标记该点为-1;否则在mask图像中标记该点为四邻域中大于0的那个值(如果有多个大于0的值,则按照左右上下的顺序取)。
同理,对于同一个128灰度区域包围的几个不同的种子点区域,他们的灰度值要设置的不同,那样在扩张不同水区域接触的时候才能够分开。
其实,什么前景背景对于watershed函数来说根本就没有区别,就是不同灰度值能够表示不同的注水点。以这些注水点为起点开始分水岭算法的实现,而不是之前所想的128的背景图部分是不动的。
同样需要注意的还有,opencv自带的分水岭算法的涨水方式和传统的涨水方式不同,在一片论文上我看到有对OpenCV分水岭算法进行改进,指出OpenCV分水岭算法在判断下一步对何种像素点进行涨水时,依据的是已经被标记为-2,也就是mark边缘和mark边缘的像素差的绝对值的大小。将其放入q队列(0-255个位置分别记录对应灰度值大小的点的位置)中,再从小到大搜寻q队列,对找到的第一个灰度进行涨水。这个就会导致一些过漫水的问题。
那篇论文名称为:《OpenCV分水岭算法的改进及其在细胞分割中的应用_张羽》,我按照这篇论文中提出的方法进行对源码的修改了,效果也不尽人意,如果哪位看到这篇文章并成功修改,效果也不错,请务必联系我。(如果这篇论文的作者看到了,也请帮助一下我这个初学者,具体应该如何修改。)
以下附上不同灰度种子改前改后的结果
:
:
其实最后的结果也不是很好,很有可能是我种子点的给出以及原图像有点太差。不过意思到位了,大家看懂就行。
错误定义mark图展示
这里就是把所有的种子点的像素都设置成了255,就会出现上面第一幅图的结果。也就是没分开。
- OpenCV分水岭watershed的应用注意
- opencv 分水岭算法watershed
- 使用OpenCV和C++实现的分水岭算法(Watershed)
- 使用OpenCV和C++实现的分水岭算法(Watershed)
- opencv之分水岭算法watershed源码注释
- OpenCV分水岭分割函数:watershed()介绍
- OpenCV库中watershed函数(分水岭算法)的详细使用例程
- watershed分水岭算法的matlab例子详解
- waterShed-分水岭算法的原理及实现
- 分水岭算法(Watershed algorithm)与OpenCV实现
- OpenCV 源码中分水岭算法 watershed 函数源码注解
- Opencv分水岭算法——watershed自动图像分割用法
- Opencv分水岭算法——watershed自动图像分割用法
- opencv之分水岭算法 watershed 函数源码注解
- Opencv分水岭算法——watershed自动图像分割用法
- 基于边缘的图像分割——分水岭算法(watershed)算法分析(附opencv源码分析)
- opencv的分水岭分割
- 分水岭算法(Watershed Algorithm)
- 打印九九乘法表(难度:半颗星)
- Unity编辑器扩展学习笔记(二)——给创建的菜单选项添加快捷键
- jar常用命令
- canvas学习笔记
- C语言函数详解
- OpenCV分水岭watershed的应用注意
- 深入理解Spring Redis的使用 (五)、常见问题汇总
- java基础--跳转控制语句return break continue
- 4886: [Lydsy2017年5月月赛]叠塔游戏
- 面试题集锦
- codeforces round #415 C.Do you want a Date?
- linux运维-postfix邮件的处理
- 深入理解Spring Redis的使用 (六)、用Spring Aop 实现注解Dao层的自动Spring Redis缓存
- 2017年 3月到2017年6月