OpenCV图像分割中的分水岭算法原理与应用详解-创新互联
图像分割是按照一定的原则,将一幅图像分为若干个互不相交的小局域的过程,它是图像处理中最为基础的研究领域之一。目前有很多图像分割方法,其中分水岭算法是一种基于区域的图像分割算法,分水岭算法因实现方便,已经在医疗图像,模式识别等领域得到了广泛的应用。
创新互联是一家专业提供洪山企业网站建设,专注与成都做网站、网站制作、H5页面制作、小程序制作等业务。10年已为洪山众多企业、政府机构等服务。创新互联专业的建站公司优惠进行中。1.传统分水岭算法基本原理
分水岭比较经典的计算方法是L.Vincent于1991年在PAMI上提出的[1]。传统的分水岭分割方法,是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中每一像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域称为集水盆地,而集水盆地的边界则形成分水岭。分水岭的概念和形成可以通过模拟浸入过程来说明。在每一个局部极小值表面,刺穿一个小孔,然后把整个模型慢慢浸人水中,随着浸入的加深,每一个局部极小值的影响域慢慢向外扩展,在两个集水盆汇合处构筑大坝如下图所示,即形成分水岭。
传统分水岭算法示意图
然而基于梯度图像的直接分水岭算法容易导致图像的过分割,产生这一现象的原因主要是由于输入的图像存在过多的极小区域而产生许多小的集水盆地,从而导致分割后的图像不能将图像中有意义的区域表示出来。所以必须对分割结果的相似区域进行合并。
[1]L.Vincent, P Soille. Watersheds in digital space: An efficientalgorithms based on immersion simulation[J]. IEEE Trans. on Pattern Analysisand Machine Intelligence, 1991, 13(6): 583-598.
2.改进的分水岭算法基本原理
因为传统分水岭算法存在过分割的不足,OpenCV提供了一种改进的分水岭算法,使用一系列预定义标记来引导图像分割的定义方式。使用OpenCV的分水岭算法cv::wathershed,需要输入一个标记图像,图像的像素值为32位有符号正数(CV_32S类型),每个非零像素代表一个标签。它的原理是对图像中部分像素做标记,表明它的所属区域是已知的。分水岭算法可以根据这个初始标签确定其他像素所属的区域。传统的基于梯度的分水岭算法和改进后基于标记的分水岭算法示意图如下图所示。
传统基于梯度的分水岭算法和基于标记的分水岭算法原理图
从上图可以看出,传统基于梯度的分水岭算法由于局部最小值过多造成分割后的分水岭较多。而基于标记的分水岭算法,水淹过程从预先定义好的标记图像(像素)开始,较好的克服了过度分割的不足。本质上讲,基于标记点的改进算法是利用先验知识来帮助分割的一种方法。因此,改进算法的关键在于如何获得准确的标记图像,即如何将前景物体与背景准确的标记出来。
3.基于标记点的分水岭算法应用
基于标记点的分水岭算法应用步骤
● 封装分水岭算法类
● 获取标记图像
获取前景像素,并用255标记前景
获取背景像素,并用128标记背景,未知像素,使用0标记
合成标记图像
● 将原图和标记图像输入分水岭算法
● 显示结果
(1)封装分水岭算法类
将分水岭算法cv::watershed(image,markers)封装进类WatershedSegmenter,并保存为头文件以便于操作。(本段封装代码参考《OpenCV计算机视觉编程攻略(第二版)》)
#if !defined WATERSHS #define WATERSHS #include#include class WatershedSegmenter { private: cv::Mat markers; public: void setMarkers(const cv::Mat& markerImage) { // Convert to image of ints markerImage.convertTo(markers,CV_32S); } cv::Mat process(const cv::Mat &image) { // Apply watershed cv::watershed(image,markers); return markers; } // Return result in the form of an image cv::Mat getSegmentation() { cv::Mat tmp; // all segment with label higher than 255 // will be assigned value 255 markers.convertTo(tmp,CV_8U); return tmp; } // Return watershed in the form of an image以图像的形式返回分水岭 cv::Mat getWatersheds() { cv::Mat tmp; //在变换前,把每个像素p转换为255p+255(在conertTo中实现) markers.convertTo(tmp,CV_8U,255,255); return tmp; } }; #endif
另外有需要云服务器可以了解下创新互联建站www.cdcxhl.com,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
文章标题:OpenCV图像分割中的分水岭算法原理与应用详解-创新互联
分享链接:http://pwwzsj.com/article/cciedj.html