OpenCV2 使用分水岭算法对图像分割的个人理解 cv::watershed()

本文详细介绍了OpenCV2中的分水岭算法,通过将图像视为地形,利用拓扑理论进行图像分割。内容包括算法原理、过度分割问题、OpenCV的改进方法,特别是对预定义标记的理解。作者分享了个人见解,并提供了相关代码示例,帮助读者更好地掌握cv::watershed()函数的使用。
摘要由CSDN通过智能技术生成

本文是基于《opecv2 计算机视觉编程手册》中的案例对分水岭算法进行解读。

先介绍一下分水岭分割方法。它是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中每一点像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域称为集水盆,而集水盆的边界则形成分水岭。分水岭的概念和形成可以通过模拟浸入过程来说明。在每一个局部极小值表面,刺穿一个小孔,然后把整个模型慢慢浸入水中,随着浸入的加深,每一个局部极小值的影响域慢慢向外扩展,在两个集水盆汇合处构筑大坝,即形成分水岭。

一般的分水岭算法会对微弱边缘,图像中的噪声,物体表面细微的灰度变化造成过度的分割。opencv中的分水岭算法对此进行了改进,它使用预定义的一组标记来引导对图像的分割。理解这一节,关键是理解这个标记。书上这一节的内容对这个标记讲得很模糊,网上也搜了很多cv::watershed(),大部分内容是opencv1.0案例使用鼠标响应事件的,有个别是opencv2.0的案例,但都只是复制代码,并未做一些解读。这里我谈谈自己的一些看法,希望对大家有所帮助,如有理解不正确的地方还请高手多多指教。
watershedSegmenter.h

#if !defined WATERSHS
#define WATERSHS

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

class WatershedSegmenter {
   

  private:
      //用来表示标记(图)
      cv::Mat markers;

  public:
       //设置标记图
      void setMarkers(const cv::Mat& markerImage) {

        //watershed()的输入参数必须为一个32位有符号的标记,所以要先进行转换 
        markerImage.convertTo(markers,CV_32S);
      }
      //执行watershed()
      cv::Mat process(const cv::Mat &image) {

        // Apply watershed
        cv::watershed(image,markers);

        return markers;
      }

      // 以图像
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值