OpenCV图像分割(2)分水岭算法图像分割函数watershed()的使用

news2024/9/25 14:22:27
  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

使用分水岭算法执行基于标记的图像分割。

该函数实现了分水岭算法的一种变体,即无参数基于标记的分割算法,在文献 [186] 中有描述。

在将图像传递给函数之前,你需要在图像的标记中大致勾勒出所期望的区域,并使用正数(>0)索引。因此,每一个区域表现为一个或多个连接组件,其像素值为1、2、3等。这样的标记可以从二值掩模中通过 findContours 和 drawContours 获取(参见watershed.cpp演示)。标记是未来图像区域的“种子”。标记中的所有其他像素,即那些与轮廓区域的关系未知且应由算法定义的像素,应设置为0。在函数的输出中,标记中的每一个像素都被设置为“种子”组件的值,或者在区域之间的边界处设置为-1。
OpenCV 中的 watershed() 函数是一种用于图像分割的技术,它基于分水岭算法来分割图像中的不同区域。分水岭算法通常用于分割那些彼此紧密相连的对象,特别是当对象之间没有清晰的边界时。
注意
任何两个相邻的连通组件不一定被分水岭边界(-1的像素)分隔;例如,它们可以在传递给函数的初始标记图像中相互接触

函数原型


void cv::watershed	
(
	InputArray 	image,
	InputOutputArray 	markers 
)	

参数

  • 参数mage 输入的8位3通道图像。
  • 参数markers 输入/输出的32位单通道图像(标记地图)。它应该与image具有相同的尺寸。

代码示例


#include <iostream>
#include <opencv2/opencv.hpp>

int main()
{
    // 读取图像
    cv::Mat img = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/fruit_small.jpg" );
    if ( img.empty() )
    {
        std::cout << "Could not open or find the image!" << std::endl;
        return -1;
    }

    // 转换为灰度图像
    cv::Mat gray;
    cvtColor( img, gray, cv::COLOR_BGR2GRAY );

    // 二值化处理
    cv::Mat thresh;
    threshold( gray, thresh, 0, 255, cv::THRESH_BINARY_INV + cv::THRESH_OTSU );

    // 噪声去除
    cv::Mat kernel = cv::getStructuringElement( cv::MORPH_ELLIPSE, cv::Size( 3, 3 ) );
    morphologyEx( thresh, thresh, cv::MORPH_OPEN, kernel, cv::Point( -1, -1 ), 2 );

    // 距离变换
    cv::Mat dist;
    distanceTransform( thresh, dist, cv::DIST_L2, 3 );
    normalize( dist, dist, 0, 1.0, cv::NORM_MINMAX );

    // 标记生成
    cv::Mat markers = cv::Mat::zeros( dist.size(), CV_32S );
    cv::Mat dist8u;
    dist.convertTo( dist8u, CV_8U );
    std::vector< std::vector< cv::Point > > contours;
    std::vector< cv::Vec4i > hierarchy;
    findContours( dist8u, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE );

    // 标记轮廓
    for ( size_t i = 0; i < contours.size(); i++ )
    {
        cv::drawContours( markers, contours, static_cast< int >( i ), static_cast< int >( i + 1 ), -1 );
    }

    // 设置背景区域
    cv::Mat marker32 = markers.clone();
    cv::Mat markerAc = cv::Mat::zeros( markers.size(), CV_8U );
    for ( int i = 0; i < img.rows; i++ )
    {
        for ( int j = 0; j < img.cols; j++ )
        {
            if ( marker32.at< int >( i, j ) == -1 )
            {
                markerAc.at< uchar >( i, j ) = 255;
            }
        }
    }
    cv::morphologyEx( markerAc, markerAc, cv::MORPH_CLOSE, kernel );

    // 应用分水岭算法
    cv::watershed( img, markers );

    // 处理结果
    std::vector< cv::Vec3b > colors( 256 );
    for ( int i = 0; i < colors.size(); i++ )
    {
        colors[ i ][ 0 ] = static_cast< unsigned char >( ( i * 127 / 255 ) % 255 );
        colors[ i ][ 1 ] = static_cast< unsigned char >( ( i * 251 / 255 ) % 255 );
        colors[ i ][ 2 ] = static_cast< unsigned char >( ( i * 237 / 255 ) % 255 );
    }

    cv::Mat dst = cv::Mat::zeros( markers.size(), CV_8UC3 );
    for ( int i = 0; i < markers.rows; i++ )
    {
        for ( int j = 0; j < markers.cols; j++ )
        {
            int index = markers.at< int >( i, j );
            if ( index == -1 )
                dst.at< cv::Vec3b >( i, j ) = cv::Vec3b( 0, 0, 255 );  // 分水岭区域
            else
                dst.at< cv::Vec3b >( i, j ) = colors[ index ];
        }
    }

    // 显示结果
    cv::imshow( "Original Image", img );
    cv::imshow( "Threshold Image", thresh );
    cv::imshow( "Markers Before Watershed", markerAc );
    cv::imshow( "Segmented Image", dst );
    cv::waitKey( 0 );

    return 0;
 }

运行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2163793.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GPG(GNU Privacy Guard)简介

GPG&#xff08;GNU Privacy Guard&#xff09;简介 加密基础 对称加密 对称加密是一种加密方式&#xff0c;其中加密和解密使用相同的密钥。常见的对称加密算法包括AES和DES。这种方法的优点是速度快&#xff0c;但缺点是密钥分发和管理比较困难&#xff0c;一旦密钥泄露&a…

网络安全-jsp绕过

一、思路(这里给出jsp的WebShell样本) 1.1 加载字节码getshell <% page import"com.sun.org.apache.bcel.internal.util.ClassLoader" %> <html> <body> <h2>BCEL字节码的JSP Webshell</h2> <%String bcelCode "$$BCEL$$$l…

零基础转行学网络安全怎么样?能找到什么样的工作?

网络安全对于现代社会来说变得越来越重要&#xff0c;但是很多人对于网络安全的知识却知之甚少。那么&#xff0c;零基础小白可以学网络安全吗&#xff1f;答案是肯定的。 零基础转行学习网络安全是完全可行的&#xff0c;但需要明确的是&#xff0c;网络安全是一个既广泛又深入…

常用的10款加密软件排行榜(2024年办公文件加密干货收藏)

随着数据泄露事件的增加和隐私安全意识的提升&#xff0c;文件加密已经成为企业和个人保护敏感信息的必备手段。无论是防止外部攻击&#xff0c;还是内部数据泄露&#xff0c;文件加密工具都是重要的防护措施。以下是2024年最常用的10款办公文件加密软件&#xff0c;帮助你在工…

全新热门电商API接口,实现闲鱼商品详细搜索功能

近年来&#xff0c;电商行业蓬勃发展&#xff0c;API&#xff08;Application Programming Interface&#xff09;接口已经成为电商平台的重要组成部分。API接口不仅可以实现平台间的数据交互&#xff0c;还可以为开发者提供丰富的功能&#xff0c;满足用户多样化的需求。在这个…

吴师兄:非科班程序员,创作出Github标星75.3K的宝藏项目,一周爆火……

这是《开发者说》的第18期&#xff0c;今天我们采访的是在Github上传LeetCode动画题解&#xff0c;获得75.3K标星宝藏项目的程序员吴师兄。 吴师兄从985大学毕业&#xff0c;从通信工程外包零基础转码程序员&#xff0c;逐渐进入一些中厂和大厂&#xff0c;工资也从三四千起步…

靶向捕获探针设计软件包

&#x1f3c6;本文收录于《全栈Bug调优(实战版)》专栏&#xff0c;主要记录项目实战过程中所遇到的Bug或前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&…

什么是容性负载箱?

容性负载箱是用于模拟电网中感性负载的装置&#xff0c;通常由电容器、电抗器等元件组成。在电力系统中&#xff0c;负载箱被广泛应用于测试和评估各种电气设备的性能&#xff0c;如变压器、发电机、开关设备等。容性负载箱的主要作用是模拟实际负载对电网的影响&#xff0c;以…

用甘特图做项目计划,你就是时间管理大师!

当我们想要清晰地展现一个活动流程或项目进展时&#xff0c;如何提升对时间和项目的管理能力呢&#xff1f;本文将为你介绍一种新颖的甘特图&#xff0c;特别适合用来进行长期工作安排。借助甘特图&#xff0c;我们可以将中长期目标切分为更易掌控的短期计划&#xff0c;让计划…

无人机之可承受风速的影响因素

无人机可承受风速的影响因素是多方面的&#xff0c;这些因素共同决定了无人机在特定风速条件下的飞行稳定性和安全性。以下是一些主要的影响因素&#xff1a; 一、无人机设计与结构 无人机的大小、形状和重量都会直接影响其抗风能力。大型无人机由于具有更大的表面积和质量&am…

Linux:进程间通信之命名管道

Linux&#xff1a;进程间通信-CSDN博客 我们说匿名管道只能用于父子进程这样的关系通信&#xff0c;那么陌生进程怎么通信&#xff1f; 我们之前说父子进程能通信的最关键的地方就在于子进程复制了一份父进程的files_struct&#xff0c;从而通过文件的inode映射同一份文件来通…

c++反汇编逆向还原指令jge jg jle jl jne je

c反汇编逆向还原jge jg jle jl jne je所还原的c代码 c反汇编逆向还原&#xff0c;if语句、赋值、算数|逻辑运算符(> 、>、、<、<、if中的&&、!、||) 在汇编指令中 jge 前面>后面 jg 前面>后面 jle 前面<后面 jl 前面<后面 jne 前面不等…

从零开始学习Python

目录 从零开始学习Python 引言 环境搭建 安装Python解释器 选择IDE 基础语法 注释 变量和数据类型 变量命名规则 数据类型 运算符 算术运算符 比较运算符 逻辑运算符 输入和输出 控制流 条件语句 循环语句 for循环 while循环 循环控制语句 函数和模块 定…

酒店智能插座有什么用途

作为提升住宿体验的关键一环&#xff0c;酒店智能插座正以其独特的功能和便捷性&#xff0c;悄然改变着旅客的居住体验。本文将深入探讨酒店智能插座的多种用途。 一、能源管理与节能减排 酒店智能插座首要的功能之一在于其强大的能源管理能力。通过内置的传感器和智能算法&…

低成本搭建企业专属云电脑 贝锐向日葵推出私有化云电脑服务

作为一种硬件虚拟化技术&#xff0c;云电脑的优势是十分显著的&#xff0c;比如可以随时随地访问&#xff0c;拥有较高的性能、无需我们购买昂贵的实体硬件、计算资源可以按需灵活拓展等等。 如今&#xff0c;越来越多的企业也开始认识到云电脑所带来的优势&#xff0c;将云电…

软考(9.22)

1 在浏览器的地址栏中输入xxxyftp.abc.can.cn&#xff0c;在该URL中( )是要访问的主机名。 A.xxxyftp B.abc C.can D.cn 协议://主机名.域名.域名后缀或IP地址(:端口号)/目录/文件名。 本题xxxyftp是主机名&#xff0c;选择A选项。 2 假设磁盘块与缓冲区大小相同&#xff0c;…

DAMODEL丹摩智算平台实践CogVideoX

文章目录 前言 一、平台账号注册并登录 二、部署CogVideoX &#xff08;一&#xff09;简介 &#xff08;二&#xff09;部署 1. 创建实例 2. 配置环境和依赖 3.预制模型与配置文件 三、开始运行 总结 前言 该文章主要记录DAMODEL丹摩智算平台实践过程与心得体会&…

【自动化测试】Appium Server如何安装和Appium Server安装困难的原因和解决方法以及常见的一些安装失败的错误和解决方法

引言 Appium Server安装过程时常出现问题&#xff0c;以下是安装Appium Server过程一些原因、常见错误和解决方法 文章目录 引言一、Appium Server如何安装1.1 Node.js 安装1.2 使用NPM安装Appium1.3 验证Appium安装1.4 运行Appium Server1.5 使用Appium Desktop&#xff08;可…

QT C++ 自学积累 『非技术文』

QT C 自学积累 『非技术文』 最近一段时间参与了一个 QT 项目的开发&#xff0c;使用的是 C 语法&#xff0c;很遗憾的是我之前从来没有接触过 C &#xff0c;大学没有开过这堂课&#xff0c;也没用自己学习过&#xff0c;所有说上手贼慢&#xff0c;到现在为止其实也不是很清楚…

经纬恒润全冗余R-EPS助力L4级自动驾驶落地

随着L4级别自动驾驶技术的逐步成熟与商业化进程加速&#xff0c;行业对车辆安全性的要求达到了新的高度。为了确保自动驾驶车辆全天候、全路况下安全运行&#xff0c;冗余系统的研发与应用成为关键。在这一背景下&#xff0c;经纬恒润开发了齿条式全冗余电动助力转向系统R-EPS&…