OpenCV开发笔记(五十九):红胖子8分钟带你深入了解分水岭算法(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106258388
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)
上一篇:《OpenCV开发笔记(五十八):红胖子8分钟带你深入了解图像的矩(图文并茂+浅显易懂+程序源码)》
下一篇:持续补充中…
前言
红胖子,来也!
做识别,有时候需求要识别物体,物体在背景上比较杂,但是其边缘与背景图相差大,这个时候可以使用分水岭算法突出两边的颜色对比度,从而更好的分割。
Demo
分水岭算法
概述
分水岭分割方法,是一种基于拓扑理论的数学形态学的分割方法,其基本思想是把图像看作是测地学上的拓扑地貌,图像中每一点像素的灰度值表示该点的海拔高度,每一个局部极小值及其影响区域称为集水盆,而集水盆的边界则形成分水岭。简单来说就是根据图像相邻的像素差值,分成不同区域,将各区域染成不同颜色,其适合使用者已经可以标记已知对象或背景中的一部分。
&emp;分水岭的概念和形成可以通过模拟浸入过程来说明。在每一个局部极小值表面,刺穿一个小孔,然后把整个模型慢慢浸入水中,随着浸入的加深,每一个局部极小值的影响域慢慢向外扩展,在两个集水盆汇合处构筑大坝,即形成分水岭。
分水岭的计算过程是一个迭代标注过程。
原理
分水岭比较经典的计算方法是L. Vincent提出的。在该算法中,分水岭计算分两个步骤,一个是排序过程,一个是淹没过程。首先对每个像素的灰度级进行从低到高排序,然后在从低到高实现淹没过程中,对每一个局部极小值在h阶高度的影响域采用先进先出(FIFO)结构进行判断及标注。
分水岭变换得到的是输入图像的集水盆图像,集水盆之间的边界点,即为分水岭。显然,分水岭表示的是输入图像极大值点。因此,为得到图像的边缘信息,通常把梯度图像作为输入图像,即
g(x,y)=grad(f(x,y))={[f(x,y)-f(x-1,y)]2[f(x,y)-f(x,y-1)]2}0.5
式中,f(x,y)表示原始图像,grad{.}表示梯度运算。
分水岭算法对微弱边缘具有良好的响应,图像中的噪声、物体表面细微的灰度变化,都会产生过度分割的现象。但同时,分水岭算法对微弱边缘具有良好的响应,是得到封闭连续边缘的保证的。
分水岭函数原型
void watershed(InputArray image, InputOutputArray markers )
- 参数一:lnputArray类型的src,输入图像,即源图像,填Mat类的对象即可,且需为8位三通道的彩色图像。
- 参数二:InputOutputArray类型的markers,在执行分水岭函数watershed之前,必须对该参数进行处理,它应该包含不同区域的轮廓,每个轮廓有一个自己唯一的编号,轮廓的定位可以通过Opencv中findContours方法实现,这个是执行分水岭之前的要求。
Demo涉及到的相关知识
均值滤波:《OpenCV开发笔记(十五):算法基础之线性滤波-均值滤波》
canny边缘检测:《OpenCV开发笔记(三十七):红胖子8分钟带你深入了解边缘检测和Canny算子边缘检测(图文并茂+浅显易懂+程序源码)》
查找与绘制轮廓:《OpenCV开发笔记(四十九):红胖子8分钟带你深入了解轮廓识别(图文并茂+浅显易懂+程序源码)》
Demo源码
void OpenCVManager::testWatersheed()
{
QString fileName1 =
"E:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/5.jpg";
int width = 400;
int height = 300;
cv::Mat srcMat = cv::imread(fileName1.toStdString());
cv::resize(srcMat, srcMat, cv::Size(width, height));
cv::String windowName = _windowTitle.toStdString();
cvui::init(windowName);
cv::Mat windowMat = cv::Mat(cv::Size(srcMat.cols * 2, srcMat.rows * 3),
srcMat.type());
int threshold1 = 200;
int threshold2 = 100;
while(true)
{
windowMat = cv::Scalar(0, 0, 0);
cv::Mat mat;
cv::Mat tempMat;
// 原图先copy到左边
mat = windowMat(cv::Range(srcMat.rows * 0, srcMat.rows * 1),
cv::Range(srcMat.cols * 0, srcMat.cols * 1));
cv::addWeighted(mat, 0.0f, srcMat, 1.0f, 0.0f, mat);
{
// 灰度图
cv::Mat grayMat;
cv::cvtColor(srcMat, grayMat, cv::COLOR_BGR2GRAY);
// copy
mat = windowMat(cv::Range(srcMat.rows * 0, srcMat.rows * 1),
cv::Range(srcMat.cols * 1, srcMat.cols * 2));
cv::Mat grayMat2;
cv::cvtColor(grayMat, grayMat2, cv::COLOR_GRAY2BGR);
cv::addWeighted(mat, 0.0f, grayMat2, 1.0f, 0.0f, mat);
// 均值滤波
cv::blur(grayMat, tempMat, cv::Size(3, 3));
cvui::printf(windowMat, width * 1 + 20, height * 1 + 20, "threshold1");
cvui::trackbar(windowMat, width * 1 + 20, height * 1 + 40, 200, &threshold1, 0, 255);
cvui::printf(windowMat, width * 1 + 20, height * 1 + 100, "threshold2");
cvui::trackbar(windowMat, width * 1 + 20, height * 1 + 120, 200, &threshold2, 0, 255);
// canny边缘检测
cv::Canny(tempMat, tempMat, threshold1, threshold2);
// copy
mat = windowMat(cv::Range(srcMat.rows * 1, srcMat.rows * 2),
cv::Range(srcMat.cols * 0, srcMat.cols * 1));
cv::cvtColor(tempMat, grayMat2, cv::COLOR_GRAY2BGR);
cv::addWeighted(mat, 0.0f, grayMat2, 1.0f, 0.0f, mat);
// 查找轮廓
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(tempMat, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);
// 绘制轮廓
cv::Mat maskers = cv::Mat::zeros(grayMat.size(), CV_32SC1);
maskers = cv::Scalar::all(0);
cv::Mat tMat = srcMat.clone();
tMat = cv::Scalar(0, 0, 0);
for(int index = 0; index < contours.size(); index++)
{
cv::drawContours(maskers, contours, index, cv::Scalar::all(index+1));
cv::drawContours(tMat, contours, index, cv::Scalar(0, 0, 255));
}
// copy
mat = windowMat(cv::Range(srcMat.rows * 2, srcMat.rows * 3),
cv::Range(srcMat.cols * 0, srcMat.cols * 1));
cv::addWeighted(mat, 0.0f, tMat, 1.0f, 0.0f, mat);
// 分水岭
cv::watershed(srcMat, maskers);
cv::Mat watershedImage(maskers.size(), CV_8UC3) ;
for(int i = 0 ; i < maskers.rows ; i++ )
{
for(int j = 0 ; j < maskers.cols; j++)
{
int index = maskers.at<int>(i, j);
if(index == -1)
{
watershedImage.at<cv::Vec3b>(i, j) = cv::Vec3b(255, 255, 255);
}else if( index <= 0 || index > contours.size() )
{
watershedImage.at<cv::Vec3b>(i, j) = cv::Vec3b(0, 0, 0);
}else
{
watershedImage.at<cv::Vec3b>(i, j) = cv::Vec3b((index - 5 > 0 ? 0 : index % 5) * 50,
(index - 5 > 0 ? index - 5 : 0) % 5 * 50,
(index - 10 > 0 ? index - 10 : 0) % 5 * 50);
}
// 混合灰皮图和 分水岭效果 图 并显 示最终的窗 口
}
}
// copy
mat = windowMat(cv::Range(srcMat.rows * 2, srcMat.rows * 3),
cv::Range(srcMat.cols * 1, srcMat.cols * 2));
cv::addWeighted(mat, 0.0f, watershedImage, 1.0f, 0.0f, mat);
}
// 更新
cvui::update();
// 显示
cv::imshow(windowName, windowMat);
// esc键退出
if(cv::waitKey(25) == 27)
{
break;
}
}
}
工程模板:对应版本号v1.53.0
对应版本号v1.53.0
上一篇:《OpenCV开发笔记(五十八):红胖子8分钟带你深入了解图像的矩(图文并茂+浅显易懂+程序源码)》
下一篇:持续补充中…
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106258388
OpenCV开发笔记(五十九):红胖子8分钟带你深入了解分水岭算法(图文并茂+浅显易懂+程序源码)的更多相关文章
- OpenCV开发笔记(六十五):红胖子8分钟带你深入了解ORB特征点(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(六十四):红胖子8分钟带你深入了解SURF特征点(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(五十六):红胖子8分钟带你深入了解多种图形拟合逼近轮廓(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(五十五):红胖子8分钟带你深入了解Haar、LBP特征以及级联分类器识别过程(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(六十九):红胖子8分钟带你使用传统方法识别已知物体(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(七十一):红胖子8分钟带你深入级联分类器训练
前言 红胖子,来也! 做图像处理,经常头痛的是明明分离出来了(非颜色的),分为几块区域,那怎么知道这几块区域到底哪一块是我们需要的,那么这部分就涉及到需要识别了. 识别可以自己写模板匹配.特征 ...
- OpenCV开发笔记(七十二):红胖子8分钟带你使用opencv+dnn+tensorFlow识别物体
前言 级联分类器的效果并不是很好,准确度相对深度学习较低,本章使用opencv通过tensorflow深度学习,检测已有模型的分类. Demo 可以猜测,1其实是人,18序号类是狗 ...
- OpenCV开发笔记(七十三):红胖子8分钟带你使用opencv+dnn+yolov3识别物体
前言 级联分类器的效果并不是很好,准确度相对深度学习较低,上一章节使用了dnn中的tensorflow,本章使用yolov3模型,识别出具体的分类. Demo 320x320,置信度0 ...
- .Net开发笔记(十九) 创建一个可以可视化设计的对象
阅读本篇博客之前需要了解VS窗体设计器的工作原理,详细可参见本系列博客(十).(十一).(十二).必须需要知道的一条结论就是:处于窗体设计器(Form Designer)中的任何组件(包含控件,下同) ...
- Java开发笔记(十九)规律变化的for循环
前面介绍while循环时,有个名叫year的整型变量频繁出现,并且它是控制循环进出的关键要素.不管哪一种while写法,都存在三处与year有关的操作,分别是“year = 0”.“year<l ...
随机推荐
- [转帖]Jmeter笔记:使用Jmeter向kafka发送消息
https://www.cnblogs.com/daydayup-lin/p/14124816.html 日常工作中有时候需要向kafka中发送消息来测试功能或者性能,这时候我们怎么办呢?我之前是自己 ...
- [转帖]Linux开源存储漫谈(2)IO性能测试利器fio
fio(Flexible I/O Tester)正是非常常用的文件系统和磁盘 I/O 性能基准测试工具.提供了大量的可定制化选项,可以用来测试,裸盘.一个单独的分区或者文件系统在各种场景下的 I/O ...
- Docker 运行 MongoDB的简单办法
Docker 运行 MongoDB的简单办法 第一步拉取镜像 docker pull mongo 第二步创建自己的目录 地址 10.24.22.240 创建目录 mkdir /mongodb 第三步 ...
- CentOS7 通过移植二进制文件的方式安装redis、nginx以及dotnet core的简单办法
新的centos机器安装预制软件比较麻烦 最简单的方法是在保证服务器或者是虚拟机硬件架构相同,并且操作系统版本差别不是很大的情况下, 直接使用其他机器已经变异好的二进制文件最为简单. 比如本次 我这边 ...
- 兄弟组件互相传递值-this.$bus.$emit与this.$bus.$on
B组件向C组件传递一个值. 一种组件间通信的方式, 适用于任意的组件间通信. 适用于任意的组件间通信. 适用于任意的组件间通信. 通过this.$bus.$emit('事件名',数据)进行提供数据 通 ...
- ElementUI实现表格(table) 行上下移动的效果
参考地址 https://blog.csdn.net/sunshine0508/article/details/88390155 看大佬的地址 <div id="app"&g ...
- 策略模式学习,使用go实现策略模式
策略模式 定义 优点 缺点 使用场景 代码实现 策略模式和工厂模式的区别 参考 策略模式 定义 策略模式定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响到客户端的使用 ...
- Paddle模型性能分析工具Profiler:定位瓶颈点、优化程序、提升性能
项目链接,fork一下即可使用 https://aistudio.baidu.com/aistudio/projectdetail/4482932?contributionType=1 Paddle模 ...
- Python xlwt数据保存到 Excel中以及xlrd读取excel文件画图
1.方法一:xlwt 1.1 安装包 pip install xlwt 1.2 保存数据到 Excel import xlwt import numpy as np import random # 新 ...
- 8.4 C++ 运算符重载
C/C++语言是一种通用的编程语言,具有高效.灵活和可移植等特点.C语言主要用于系统编程,如操作系统.编译器.数据库等:C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统.图形用户界面 ...