当前位置: 首页 > news >正文

计算机视觉全系列实战教程 (十二):图像分割(阈值分割threshold、分水岭算法watershed的使用步骤、洪水填充floodFill算法的使用)

1.图像分割概述

(1)What(什么是图像分割)

将图像划分为不同的子区域,使得同一子区域具有较高的相似性,不同的子区域具有明显的差异性

(2)Why(对图像进行分割有什么作用)

  • 医学领域:将不同组织分割成不同区域帮助分析病情
  • 军事领域:通过对图像的分割,为自动目标识别提供参数,为飞行器或武器的精准导航提供依据
  • 遥感领域:通过遥感图像分析城市地貌、作物生长情况。此外,云系分析和天气预报都离不开图像分割
  • 交通领域:车辆跟踪和车牌识别
  • 工业领域:零部件分类、质量评估等

(3)Which(有哪些图像分割的方法)

  • 基于阈值的分割方法:利用灰度直方图得到分割的阈值,利用这些阈值将图像分为几个部分,核心思想是认为同一部分的像素是同一个物体。
  • 基于边缘的分割方法:检测图像的边界以实现对图像的分割
  • 基于区域的分割方法:核心思想是将有相似特性的像素集合起来构成区域,将差异性较大的区域进行分裂
  • 基于神经网络的分割方法:这里不多赘言,现在很火…
  • 基于聚类的分割方法:依据像素相似度,使用聚类算法将像素划分为不同类别

2.基于阈值的分割

(1)固定阈值分割

将图像分为两个部分:黑和白两个区域

/*@author @还下着雨ZG
* @brief 固定阈值图像分割
* @param[in] imSrc, 待分割的图像
* @param[out] imSegment, 分割后的图像
* @param[in] threVal, 输入的阈值
* @return, 返回正整数表示图像分割成功,负整数表示失败
**/
int ImgSegmentByGlbThreVal(const cv::Mat& imSrc, cv::Mat& imSegment, int threVal)
{if(imSrc.empty()) return -1;if(threVal<0 || threVal>255) return -2;// 图像预处理cv::Mat imGray;if(imSrc.channels()==1) imGray = imSrc.clone();else if(imSrc.channels() == 3){cv::cvtColor(imSrc, imGray, cv::COLOR_RGB2GRAY);}else{return -3;}cv::GaussianBlur(imGray, imGray, cv::Size(3,3), 0);//全局阈值法cv::threshold(imGray, imSegment, threVal);return 1;
}

阈值分割函数threshold的介绍:

double cv::threshold(cv::Mat &imSrc, //输入图像,应该为单通道cv::Mat &imDst, //分割后的图像,大小和类型和imSrc相同double thresh, //表示阈值double maxval, //最大灰度值,一般设为255int type //阈值化类型,详细介绍如下所示};

参数type的介绍:type是一个枚举类型的数据

THRESH_BINARY = 0, // ( x > thresh ) ? 255 : 0
THRESH_BINARY_INV = 1, // ( x > thresh ) ? 0 : 255
THRESH_TRUNC = 2, // ( x > thresh ) ? thresh : x
THRESH_TOZERO = 3, // ( x < thresh ) ? 0 : x
THRESH_TOZERO = 4, // ( x < thresh ) ? x : 0
THRESH_MASK = 7,
THRESH_OTSU = 8, // 自动处理,图像自适应二值化,常用区间【0-255】

(2)自适应阈值分割

根据图像不同区域的亮度分布计算局部阈值,对于图像的不同区域能够自适应计算不同阈值

void cv::adaptiveThreshold(cv::Mat &imSrc, //输入的源图像cv::Mat &imDst, //输出图像double maxval, //预设满足条件的最大值int adaptMethod, //指定自适应阈值算法类型(ADAPTIVE_MEAN_C或ADAPTIVE_THRESH_GAUSSIAN_C两种)int threshType, //阈值类型(THRESH_BINARY或THRESH_BINARY_INV)int blockSize,  //领域块的大小,用于计算区域阈值(3,5,7 ...)double C, //与算法有关的参数,是一个从均值或加权均值提取的常数,可为负);

使用adaptiveThresh:

/*@author @还下着雨ZG
* @brief 自适应阈值图像分割
* @param[in] imSrc, 待分割的图像
* @param[out] imSegment, 分割后的图像
* @return, 返回正整数表示图像分割成功,负整数表示失败
**/
int ImgSegmentByAdpThre(const cv::Mat& imSrc, cv::Mat& imSegment)
{if (imSrc.empty()) return -1;cv::Mat imGray;if (imSrc.channels() == 1){cv::copyTo(imSrc, imGray, cv::Mat());}else if (imSrc.channels() == 3){cv::cvtColor(imSrc, imGray, cv::COLOR_RGB2GRAY);}else{return -2;}cv::GaussianBlur(imGray, imGray, cv::Size(3, 3), 0);int blockSize = 3;int constValue = 0;cv::adaptiveThreshold(imGray, imSegment, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, blockSize,constValue);return 1;
}

在实际使用时,大部分是先通过算子寻找边缘,然后和区域生长融合来分割图像

3.基于区域的分割

有相似特性的像素集合起来构成区域,将差异性较大的区域进行分裂

(1)分水岭算法

A.What(分水岭算法的概念)
将图像看作是测地学上的拓扑地貌,每一个像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域被称为盆地,对应得边界形成分水岭。
每一个局部极小值表面,刺穿一个小孔,然后从小孔浸水,随着浸入的加深,每一个局部极小值的影响域慢慢向外扩展,两个盆地间形成分水岭。
opencv提供的分水岭算法原型如下:

void cv::watershed(cv::Mat &imBGR, //三通道8bit的彩色图像);

B.How(如何使用分水岭算法对图像进行分割)

  • step01: 图像预处理(灰度化、滤波去噪等)
  • step02: Canny边缘检测
  • step03: 查找轮廓(findContours函数查找轮廓),并把轮廓信息按照不同编号绘制到watershed的第二次参数markers上,相当于标记注水点
  • step04: watershed分水岭算法调用
  • step05: 绘制分割出来的区域
/*@author @还下着雨ZG
* @param[in] imSrc, 输入的源图像
* @param[in] imMarks, 输出图像,分割之后的结果
* @return, 正整数表示成功,负整数表示失败
*/
int ImgDvdWatershed(const cv::Mat& imSrc, cv::Mat& imMarks)
{//step01 图像预处理:灰度+滤波cv::Mat imGray;cv::Mat imGray;if (imSrc.channels() == 1){cv::copyTo(imSrc, imGray, cv::Mat());}else if (imSrc.channels() == 3){cv::cvtColor(imSrc, imGray, cv::COLOR_RGB2GRAY);}else {return -1;}cv::GaussianBlur(imGray, imGray, cv::Size(3, 3), 2); //高斯滤波//Step02 Canny边缘检测cv::Mat imEdg(imGray.size(), CV_8UC1);cv::Canny(imGray, imEdg, 40, 110);//Step03 查找轮廓并绘制轮廓std::vector<std::vector<cv::Point>> vCnts;std::vector<cv::Vec4i> hierarchy;cv::findContours(imEdg, vCnts, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);cv::Mat imContours;if (!imMarks.empty()){imMarks.release();}imMarks = cv::Mat(imGray.size(), CV_32S, cv::Scalar::all(0));int iIdx = 0;int compCount = 0;for (; iIdx >= 0; iIdx = hierarchy[iIdx][0], compCount++){cv::drawContours(imMarks, vCnts, iIdx, cv::Scalar::all(compCount + 1), 1, 8, hierarchy);cv::drawContours(imContours, vCnts, iIdx, cv::Scalar(255), 1, 8, hierarchy);}cv::Mat imRGB;if (imSrc.channels() == 1){cv::cvtColor(imSrc, imRGB, cv::COLOR_GRAY2RGB);}else if (imSrc.channels() == 3){imRGB = imSrc.clone();}//Step04 调用分水岭算法cv::watershed(imRGB, imMarks);//marks既是输入参数又是输出参数imRGB.release();return 1;
}

说明:该函数输出参数imMarks图像,同一区域用相同的数值标识,分水岭用-1标识

(2)洪水填充法分割图像

该算法通常对边缘图像进行操作,可用于分割出比较完整的外轮廓

int cv::floodFill(cv::Mat &imSrc, //输入图像cv::Point seedPt, //填充的起始点cv::Scalar newVal, //填充的像素值cv::Rect *rect=0, //将要重绘区域的最小边界矩形区域cv::Scalar loDiff = cv::Scalar(), //像素值负差的最大值cv::Scalar upDiff = cv::Scalar(), //像素值正差的最大值int flags = 4 //操作标识符);

相关文章:

计算机视觉全系列实战教程 (十二):图像分割(阈值分割threshold、分水岭算法watershed的使用步骤、洪水填充floodFill算法的使用)

1.图像分割概述 (1)What(什么是图像分割) 将图像划分为不同的子区域&#xff0c;使得同一子区域具有较高的相似性&#xff0c;不同的子区域具有明显的差异性 (2)Why(对图像进行分割有什么作用) 医学领域&#xff1a;将不同组织分割成不同区域帮助分析病情军事领域&#xff…...

Linux的免交互

交互&#xff1a;我们发出指令控制程序的运行&#xff0c;程序在接收到指令之后按照指令的效果做出对应的反应。 免交互&#xff1a;间接的通过第三方的方式把指令传送给程序&#xff0c;不用直接的下达指令。 1、here document免交互 ere document免交互&#xff1a;是命令…...

查看es p12证书文件过期方法

查看证书过期时间: openssl pkcs12 -in elastic-certificates.p12 -nokeys -out elastic-certificates.crt (需要输入证书生成时配置密码) openssl x509 -enddate -noout -in elastic-certificates.crt...

1.8 无符号大数加、减运算

作者 李卫明 单位 杭州电子科技大学 1.8 无符号大数加、减运算。程序设计中经常遇到无符号大数加、减运算问题&#xff0c;请在样例程序Ex1.4基础上实现无符号大数减运算。题目要求输入两个无符号大数&#xff0c;保证一个大数不小于第二个大数&#xff0c;输出它们的和、差。…...

Java常用类--包装类

包装类 一方面出于性能方面的考虑&#xff0c;java为数值使用基本类型&#xff0c;而不是对象。基本类型不是对象层次的组成部分&#xff0c;它们不继承Object。 另一方面有时需要创建表示基本类型的对象&#xff0c;例如集合类只处理对象。为了在类中存储基本类型&#xff0c;…...

SpringMvcの拦截器全局异常处理

一、拦截器 我们在网上发贴子的时候如果没有登录&#xff0c;点击发送按钮会提示未进行登录&#xff0c;跳转到登录页面。这样的功能是如何实现的。 1、 拦截器的作用 Spring MVC 的处理器拦截器类似于Servlet开发中的过滤器Filter&#xff0c;用于对处理器进行预处理和后处理…...

JVM虚拟机的组成

一、为什么要学习 JVM &#xff1f; 1. “ ⾯试造⽕箭&#xff0c;⼯作拧螺丝” &#xff0c; JVM 属于⾯试官特别喜欢提问的知识点&#xff1b; 2. 未来在⼯作场景中&#xff0c;也许你会遇到以下场景&#xff1a; 线上系统突然宕机&#xff0c;系统⽆法访问&#xff0c;甚⾄直…...

探索CSS clip-path: polygon():塑造元素的无限可能

在CSS的世界里&#xff0c;clip-path 属性赋予了开发者前所未有的能力&#xff0c;让他们能够以非传统的方式裁剪页面元素&#xff0c;创造出独特的视觉效果。其中&#xff0c;polygon() 函数尤其强大&#xff0c;它允许你使用多边形来定义裁剪区域的形状&#xff0c;从而实现各…...

【华为OD机试B卷】单词接龙(C++/Java/Python)

题目 题目描述 单词接龙的规则是: 可用于接龙的单词首字母必须要前一个单词的尾字母相同;当存在多个首字母相同的单词时,取长度最长的单词,如果长度也相等,则取字典序最小的单词;已经参与接龙的单词不能重复使用。现给定一组全部由小写字母组成单词数组,并指定其中的一个…...

项目实训-vue(十七)

项目实训-vue&#xff08;十七&#xff09; 文章目录 项目实训-vue&#xff08;十七&#xff09;1.概述2.问诊类型3.问诊时间统计4.看诊时间统计 1.概述 本篇博客将记录我在数据统计页面中的工作。因为项目并未实际运行&#xff0c;因此我们拟定了一些数据&#xff0c;并构建了…...

Android10 SystemUI系列 需求定制(二)隐藏状态栏通知图标,锁屏通知,可定制包名,渠道等

一、前言 SystemUI 所包含的界面和模块比较多,这一节主要分享一下状态栏通知图标和通知栏的定制需求:隐藏状态栏通知图标,锁屏通知,可定制包名,渠道等 来熟悉一下Systemui。 二、准备工作 按照惯例先找到核心类。这里提前说一下,这个需求的修改方法更多,笔者这里也只…...

Linux:RAID磁盘阵列

目录 一、RAID&#xff08;磁盘阵列&#xff09; 1.1、概念 1.2、RAID 0&#xff08;条带化存储&#xff09; 1.3、RAID 1&#xff08;镜像存储&#xff09; 1.4、RAID 5 1.5、RAID 6 1.6、RAID 10 (先做镜像&#xff0c;再做条带) 二、创建RAID 2.1、建立RAID 0 …...

MongoDB和AI 赋能行业应用:零售

欢迎阅读“MongoDB 和 AI 赋能行业应用”系列的第三篇。 本系列重点介绍 AI 应用于不同行业的关键用例&#xff0c;涵盖制造业和汽车行业、金融服务、零售、电信和媒体、保险以及医疗保健行业。 利用生成式 AI 技术&#xff08;Gen AI&#xff09;&#xff0c;零售商可以创造…...

MQ~消息队列能力、AMQP协议、现有选择(Kafka、RabbitMQ、RocketMQ 、Pulsar)

消息队列 消息队列看作是一个存放消息的容器&#xff0c;当我们需要使用消息的时候&#xff0c;直接从容器中取出消息供自己使用即可。由于队列 Queue 是一种先进先出的数据结构&#xff0c;所以消费消息时也是按照顺序来消费的。 常⽤的消息队列主要这 五 种&#xff0c;分别…...

开源网安参与编制的《代码大模型安全风险防范能力要求及评估方法》正式发布

​代码大模型在代码生成、代码翻译、代码补全、错误定位与修复、自动化测试等方面为研发人员带来了极大便利的同时&#xff0c;也带来了对安全风险防范能力的挑战。基于此&#xff0c;中国信通院依托中国人工智能产业发展联盟&#xff08;AIIA&#xff09;&#xff0c;联合开源…...

【树状数组 队列】1505. 最多 K 次交换相邻数位后得到的最小整数

本文涉及知识点 树状数组 队列 LeetCode1505. 最多 K 次交换相邻数位后得到的最小整数 给你一个字符串 num 和一个整数 k 。其中&#xff0c;num 表示一个很大的整数&#xff0c;字符串中的每个字符依次对应整数上的各个 数位 。 你可以交换这个整数相邻数位的数字 最多 k 次…...

【附精彩文章合辑】当谈到程序的“通用性”与“过度设计”的困境时,我们可以通过一些具体的例子来更直观地阐述这些解决方案

当谈到程序的“通用性”与“过度设计”的困境时&#xff0c;我们可以通过一些具体的例子来更直观地阐述这些解决方案。以下是一些示例&#xff1a; 一、明确需求与目标 例子1&#xff1a;在线购物平台 需求分析&#xff1a;平台需要支持用户注册、登录、浏览商品、下单购买、…...

Word中删除空白页

① 文字后面出现的空白页 把鼠标放在空白页的位置&#xff0c;按住Ctrl Delete即可。 ② 表格后面的空白页 把鼠标放在空白页左侧&#xff0c;直到出现一个空白的箭头&#xff0c;点击一下选中空白页&#xff0c;然后再Ctrl D&#xff0c;打开字体选项卡&#xff0c;在效果中…...

30.Netty进阶-黏包半包解决方案-短链接

客户端发送一次完整的消息,然后就把与服务端的链接断开。服务端读到的结果就是-1。 服务器就知道 从链接建立到断开,发送的数据是一条完整的数据。 客户端代码 package com.xkj.nian;import io.netty.bootstrap.Bootstrap; import io.netty.buffer.ByteBuf; import io.net…...

斜堆(数据结构篇)

数据结构之斜堆 斜堆 概念&#xff1a; 斜堆是左式堆的自调节形式&#xff0c;斜堆和左式堆间的关系类似于伸展树和AVL树间的关系斜堆是具有堆序性的二叉树&#xff0c;但是不存在对树的结构限制不同于左式堆&#xff0c;关于任意节点的零路径长的任何信息都不保留&#xff…...

中兴光猫高级管理:5分钟掌握zteOnu命令行工具实用指南

中兴光猫高级管理&#xff1a;5分钟掌握zteOnu命令行工具实用指南 【免费下载链接】zteOnu 项目地址: https://gitcode.com/gh_mirrors/zt/zteOnu 中兴光猫作为家庭和企业网络的核心设备&#xff0c;其隐藏的高级功能往往被普通用户界面所限制。zteOnu是一个专门为中兴…...

SpringBoot 静态资源加载失败:favicon.ico 缺失问题解析

1. 为什么你的SpringBoot项目总在报favicon.ico缺失&#xff1f; 每次启动SpringBoot项目时&#xff0c;控制台总是刷出一堆红色警告&#xff0c;其中最让人头疼的就是"No static resource favicon.ico"这个错误。作为一个踩过无数次坑的老司机&#xff0c;我可以负…...

Nunchaku-flux-1-dev在AI编程教学中的应用:代码纠错与优化

Nunchaku-flux-1-dev在AI编程教学中的应用&#xff1a;代码纠错与优化 1. 引言 编程学习过程中&#xff0c;很多初学者都会遇到这样的困境&#xff1a;写出的代码运行报错&#xff0c;却不知道错在哪里&#xff1b;代码虽然能运行&#xff0c;但效率低下、结构混乱&#xff0…...

模型安全实践:实时手机检测-通用输入图像异常检测(模糊/过曝/裁剪)

模型安全实践&#xff1a;实时手机检测-通用输入图像异常检测&#xff08;模糊/过曝/裁剪&#xff09; 1. 项目简介与核心价值 在日常的手机检测应用中&#xff0c;我们经常会遇到各种图像质量问题&#xff1a;图片模糊看不清手机细节、光线过曝导致手机轮廓丢失、或者图片被…...

AUTOSAR CANFM模块中,BusOff恢复的50ms和1000ms周期到底怎么来的?底层驱动配置详解

AUTOSAR CANFM模块中BusOff恢复时序的硬件级解析 在车载ECU开发中&#xff0c;CAN总线通信的可靠性直接关系到整车功能安全。当节点因连续错误进入BusOff状态时&#xff0c;AUTOSAR标准定义的50ms快恢复周期和1000ms慢恢复周期并非随意设定&#xff0c;而是源于CAN控制器硬件特…...

告别广告侵扰:AdGuard广告拦截扩展全平台部署指南

告别广告侵扰&#xff1a;AdGuard广告拦截扩展全平台部署指南 【免费下载链接】AdguardBrowserExtension AdGuard browser extension 项目地址: https://gitcode.com/gh_mirrors/ad/AdguardBrowserExtension 副标题&#xff1a;从新手到高手的一站式配置方案 一、价值定…...

Qwen3-TTS声音克隆入门指南:上传音频→选择语种→生成自然语音三步走

Qwen3-TTS声音克隆入门指南&#xff1a;上传音频→选择语种→生成自然语音三步走 想不想让AI用你自己的声音说话&#xff1f;或者&#xff0c;想不想用一段短短的录音&#xff0c;就克隆出能说十几种语言的“数字分身”&#xff1f;今天&#xff0c;我们就来手把手教你&#x…...

雪女-斗罗大陆模型案例分享:多种提示词生成不同风格雪女图

雪女-斗罗大陆模型案例分享&#xff1a;多种提示词生成不同风格雪女图 最近在体验“雪女-斗罗大陆-造相Z-Turbo”这个AI绘画模型时&#xff0c;我发现了一个特别有意思的现象&#xff1a;同样一个模型&#xff0c;用不同的提示词描述&#xff0c;能画出风格迥异的雪女形象。有…...

Python3.8环境配置全攻略:从零开始搭建你的第一个项目

Python3.8环境配置全攻略&#xff1a;从零开始搭建你的第一个项目 1. 为什么选择Python3.8环境 Python3.8作为Python3系列的一个重要版本&#xff0c;引入了多项新特性&#xff0c;包括海象运算符(:)、位置参数限定符(/)等语法改进&#xff0c;同时在性能上也有显著提升。对于…...

终极指南:5分钟上手BepInEx,打造你的Unity游戏插件帝国 [特殊字符]

终极指南&#xff1a;5分钟上手BepInEx&#xff0c;打造你的Unity游戏插件帝国 &#x1f680; 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx BepInEx是一款专为Unity游戏设计的强…...