最大稳定极值区域(MSER)检测

article/2025/9/13 6:33:27

Lowe和Bay提出的SIFT和SURF算法高效实现了具有尺度和旋转不变性的特征检测,但这些特征不具有仿射不变性。

区域检测针对各种不同形状的图像区域,通过对区域的旋转和尺寸归一化,可以实现仿射不变性。

MSER(Maximally Stable Extrernal Regions)是区域检测中影响最大的算法


1. 原理

MSER基于分水岭的概念:对图像进行二值化,二值化阈值取[0, 255],这样二值化图像就经历一个从全黑到全白的过程(就像水位不断上升的俯瞰图)。在这个过程中,有些连通区域面积随阈值上升的变化很小,这种区域就叫MSER。

,其中Qi表示第i个连通区域的面积,Δ表示微小的阈值变化(注水),当vi小于给定阈值时认为该区域为MSER。

显然,这样检测得到的MSER内部灰度值是小于边界的,想象一副黑色背景白色区域的图片,显然这个区域是检测不到的。因此对原图进行一次MSER检测后需要将其反转,再做一次MSER检测,两次操作又称MSER+和MSER-


2. 算法步骤

从上节可以看到,MSER的基本思路很简单,但编码实现是很需要算法和编程技巧的

以下算法步骤基于改进的分水岭算法:注水的地方固定,只有当该处的沟壑水漫出来后才能注入到另一个沟壑

此外,为方便编程,面积变化的计算方式也从双边改为单边检测,即


具体步骤(摘自Opencv2.4.9源码分析——MSER)

1、初始化栈和堆,栈用于存储组块(组块就是区域,就相当于水面,水漫过的地方就会出现水面,水面的高度就是图像的灰度值,因此用灰度值来表示组块的值),堆用于存储组块的边界像素,相当于水域的岸边,岸边要高于水面的,因此边界像素的灰度值一定不小于它所包围的区域(即组块)的灰度值。首先向栈内放入一个虚假的组块,当该组块被弹出时意味着程序的结束;


2、把图像中的任意一个像素(一般选取图像的左上角像素)作为源像素,标注该像素为已访问过,并且把该像素的灰度值作为当前值。这一步相当于往源像素这一地点注水;


3、向栈内放入一个空组块,该组块的值是当前值;


4、按照顺序搜索当前值的4-领域内剩余的边缘,对于每一个邻域,检查它是否已经被访问过,如果没有,则标注它为已访问过并检索它的灰度值,如果灰度值不小于当前值,则把它放入用于存放边界像素的堆中。另一方面,如果领域灰度值小于当前值,则把当前值放入堆中,而把领域值作为当前值,并回到步骤3;


5、累计栈顶组块的像素个数,即计算区域面积,这是通过循环累计得到的,这一步相当于水面的饱和;


6、弹出堆中的边界像素。如果堆是空的,则程序结束;如果弹出的边界像素的灰度值等于当前值,则回到步骤4;


7、从堆中得到的像素值会大于当前值,因此我们需要处理栈中所有的组块,直到栈中的组块的灰度值大于当前边界像素灰度值为止。然后回到步骤4。


至于如何处理组块,则需要进入处理栈子模块中,传入该子模块的值为步骤7中从堆中提取得到的边界像素灰度值。子模块的具体步骤为:
1)、处理栈顶的组块,即根据公式2计算最大稳定区域,判断其是否为极值区域;
2)、如果边界像素灰度值小于距栈顶第二个组块的灰度值,那么设栈顶组块的灰度值为边界像素灰度值,并退出该子模块。之所以会出现这种情况,是因为在栈顶组块和第二个组块之间还有组块没有被检测处理,因此我们需要改变栈顶组块的灰度值为边界像素灰度值(相当于这两层的组块进行了合并),并回到主程序,再次搜索组块;
3)、弹出栈顶组块,并与目前栈顶组块合并;
4)、如果边界像素灰度值大于栈顶组块的灰度值,则回到步骤1。


注:MSER算法参数较多,默认值如图3-1所示(摘自《图像局部不变性特征与描述》)


图3-1. MSER参数标准取值

3. MSER区域拟合

为了进一步对MSER得到的不规则区域进行描述和处理,需要对其进行椭圆拟合(椭圆可以反映区域的位置、尺寸、方向

1)椭圆的重心

对区域内的每个点,计算整个区域的几何0阶矩和几何一阶矩


得到整个区域的重心位置


2) 椭圆的长半轴、短半轴、角度(长半轴与x轴顺时针)

计算中心二阶矩


其中

计算该二阶矩的两个特征值,有

于是可以分别得到其长半轴、短半轴、角度



4. 代码

目前MSER的代码实现有3:OpenCV(目前操作手册上还没有这个接口的介绍)、IDIAP的实现(C++)、VLFeat的实现(C)

其中OpenCV的代码解读可参考Opencv2.4.9源码分析——MSER,其和IDIAP的实现都严格遵循着上一节的算法步骤,

IDIAP的版本只有一个mser.cpp和mser.h,很干净便于移植(如果是C实现的就更好了),其在Github上声称比VLFeat快几倍。

VLFeat是一个C实现的图像特征检测算法库,包含了SIFT、HOG、K-Means、MSER等算法

贴上IDIAP和OpenCV实现的调用代码

#IDIAPclock_t start = clock();_MSER mser8(5, 0.0005, 0.5, 0.25, 0.2, true);
_MSER mser4(5, 0.0005, 0.5, 0.25, 0.2, false);std::vector<_MSER::Region> regions[2];mser8(imgBuffer, grayImg.cols, grayImg.rows, regions[0]);// Invert the pixel values
for (int i = 0; i < grayImg.cols*grayImg.rows; ++i)imgBuffer[i] = ~imgBuffer[i];mser4(imgBuffer, grayImg.cols, grayImg.rows, regions[1]);clock_t stop = clock();for (int i = 0; i < 2; ++i)for (int j = 0; j < regions[i].size(); ++j)//IDIAP自己实现的椭圆拟合函数drawEllipse(regions[i][j], img.cols, img.rows, 3, imgBufferRGB, colors[i]);


#OpenCVcv::MSER ms(5, 0.0005, 1440);
std::vector<std::vector<cv::Point>> regions;clock_t start = clock();
ms(grayImg, regions, cv::Mat());
clock_t stop = clock();for (int i = 0; i < regions.size(); i++) cv::ellipse(img, cv::fitEllipse(regions[i]), cv::Scalar(0, 0, 255));

从实际效果来看,运行效率 OpenCV > IDIAP,VLFeat没测试

图4-1左是IDIAP的实现效果(参数与代码中一致),右是OpenCV的实现效果(其余参数隐含在features2d.hpp内)


图4-1. MSER检测


http://chatgpt.dhexx.cn/article/YC9QQNdp.shtml

相关文章

MSER最稳定极值区域源码分析

最稳定极值区域介绍 如把灰度图看成高低起伏的地形图&#xff0c;其中灰度值看成海平面高度的话&#xff0c;MSER的作用就是在灰度图中找到符合条件的坑洼。条件为坑的最小高度&#xff0c;坑的大小&#xff0c;坑的倾斜程度&#xff0c;坑中如果已有小坑时大坑与小坑的变化率。…

OpenCVSharp入门教程 特征提取①——MSER区域特征提取Maximally Stable Extremal Regions

文章目录 一、前文二、特征提取流程三、界面布局四、功能实现4.1 打开图片4.2 特征提取—源码4.3 特征提取—参数讲解4.4 特征提取—Detect和DetectRegions 五、运行效果图六、发现并解决问题七、其他问题 一、前文 MSER Maximally Stable Extremal Regions 最大极值稳定区 业…

【OpenCV 例程 300篇】247. 特征检测之最大稳定极值区域(MSER)

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程 300篇】247. 特征检测之最大稳定极值区域&#xff08;MSER&#xff09; 1. 最大稳定极值区域&#xff08;MSER&#xff09; 最大稳定极值区域&#xff08;MSER-Maximally Stable Extremal Regions&#xf…

师傅带徒弟学JavaScript-关东升-专题视频课程

师傅带徒弟学JavaScript—430人已学习 课程介绍 本课程是学习Web前端的基础课程&#xff0c;是学习Web前端框架、JavaWeb开发、Python Web开发、PHP开发和.NET Web开发前置课程。 课程收益 掌握JavaScript 讲师介绍 关东升 更多讲师课程 一个在IT领域摸爬滚打20多年的老程…

师傅带徒弟学:Python Web之Flask框架-关东升-专题视频课程

师傅带徒弟学&#xff1a;Python Web之Flask框架—317人已学习 课程介绍 Python Web是Python语言一个重要的应用方面&#xff0c;Python Web有很多&#xff0c;其中Flask和Django框架是他们的佼佼者。 Flask是一个Python实现的Web开发微框架。 课程收益 掌握Flask框架 讲师…

关东升的iOS实战系列图书 《iOS实战:入门与提高卷(Swift版)》已经上市

&#xfeff;&#xfeff; 承蒙广大读者的厚爱我的 《iOS实战&#xff1a;入门与提高卷&#xff08;Swift版&#xff09;》京东上市了&#xff0c;欢迎广大读者提出宝贵意见。http://item.jd.com/11766718.html 欢迎关注关东升新浪微博tony_关东升。 关注智捷课堂微信公共平台&…

Sharding-JDBC(一)SpringBoot集成

目录 1.背景2.简介3.依赖与配置4.表结构&#xff08;1..3&#xff09;5.测试验证5.1 批量保存5.2 列表查询 6.源码地址 1.背景 随着业务数据量的增加&#xff0c;原来所有的数据都是在一个数据库上&#xff0c;网络IO及文件IO都集中在一个数据库上&#xff0c;因此CPU、内存、…

第一篇【Python】基础-关东升-专题视频课程

第一篇【Python】基础—833人已学习 课程介绍 本书是智捷课堂开发的立体化图书中的一本&#xff0c;所谓“立体化图书”就是图书包含&#xff1a;书籍、视频、课件和服务等内容。 其中第一篇包括8章内容&#xff0c;系统介绍了Python语言的基础知识。内容包括Python语言历史…

shardingsphere-jdbc 整合 springboot

shardingsphere官网地址 https://shardingsphere.apache.org/document/5.2.0/cn/user-manual/shardingsphere-jdbc/spring-boot-starter/rules/sharding/ 当前我们演示的是水平分表 1、基础环境配置以及依赖管理 1.1 创建数据库表结构 CREATE TABLE address_0 (id bigint(…

如果张东升是个程序员

张东升是一家互联网公司的程序员&#xff0c;一直以来都勤勤恳恳老实工作。 可最近一段时间&#xff0c;行业不景气&#xff0c;老板不但下令开启了996的工作模式&#xff0c;更要命的是频频更改需求&#xff0c;弄得大家是敢怒不敢言。 时间一久&#xff0c;很多员工开始消极…

专访关东升:松耦合分层架构设计

关东升,国内知名iOS技术作家,iOS技术顾问,高级培训讲师,移动开发专家。拥有16年软件开发经验、8年培训行业经验。精通iOS、Android和 Windows Phone 7及Html5等移动开发技术。在App Store发布多款游戏和应用软件,擅长移动平台的应用和游戏类项目开发。目前主要从事iOS应用…

Java从小白到大牛第3篇 【进阶篇】-关东升-专题视频课程

Java从小白到大牛第3篇 【进阶篇】—4371人已学习 课程介绍 本视频是智捷课堂推出的一套“Java语言学习立体教程”的视频第三部分&#xff0c;读者以及观看群是初级小白&#xff0c;通过本视频的学习能够成为Java大牛。本主要内容包括&#xff1a;异常处理、集合、泛型、文…

Python项目实战:数据可视化与股票数据分析-关东升-专题视频课程

Python项目实战&#xff1a;数据可视化与股票数据分析—333人已学习 课程介绍 本视频内容包括使用Matplotlib绘制图表、MySQL数据库、Python访问数据库和Lambda表达式。 目录&#xff1a; 23.1 使用Matplotlib绘制图表 23.1.1 安装Matplotlib 23.1.2 图表基本构成要素 23.1…

【ShardingSphere技术专题】「ShardingJDBC实战阶段」SpringBoot之整合ShardingJDBC实现分库分表(JavaConfig方式)

前提介绍 ShardingSphere介绍 ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈&#xff0c;它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar&#xff08;计划中&#xff09;这3款相互独立的产品组成。 他们均提供标准化的数据分片、分布式事务和数据…

关东升给的ios学习路线图(可以借鉴)

来源&#xff1a; http://www.zhijieketang.com/classroom/3/introduction 首页 课程 免费课程 会员 关于我们 登录 注册 首页 iOS课程 iOS会员-iOS开发学习路线图 iOS会员-iOS开发学习路线图 扫二维码继续学习 (0评价) 价格&#xff1a; 1500 金币 学员(17) 课程(37) …

关东升的《从零开始学Swift》3月9日已经上架

大家一直期盼的《从零开始学Swift》于3月9日已经上架&#xff0c;它是关东升老师历时8个月的呕心沥血所编著&#xff0c;全书600多页&#xff0c;此本书基于Swift 2.x&#xff0c;通过大量案例全面介绍苹果平台的应用开发。全书共分5 部分&#xff0c;包括Swift语法篇、Cocoa T…

python从小白到大牛百度云盘_Java从小白到大牛 (关东升著) 中文pdf+mobi版[36MB]

《Java从小白到大牛》是一本Java语言学习立体教程&#xff0c;读者群是零基础小白&#xff0c;通过本书的学习能够成为Java大牛。主要内容包括&#xff1a;Java语法基础、Java编码规范、数据类型、运算符、控制语句、数组、字符串、面向对象基础、继承与多态、抽象类与接口、枚…

SpringBoot 整合 Sharding-JDBC

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、sharding-jdbc简介二、使用步骤 1.新建项目、引入依赖2.代码实战总结 前言 SpringBoot 整合 Sharding-JDBC 提示&#xff1a;以下是本篇文章正文内容&…

关东升的iOS实战系列图书 《iOS实战:传感器卷(Swift版)》已经上市

&#xfeff;&#xfeff; 承蒙广大读者的厚爱我的 《iOS实战&#xff1a;传感器卷&#xff08;Swift版&#xff09;》京东上市了&#xff0c;欢迎广大读者提出宝贵意见。http://item.jd.com/11760248.html 欢迎关注关东升新浪微博tony_关东升。 关注智捷课堂微信公共平台&…

Java从小白到大牛第1篇 Java基础-关东升-专题视频课程

Java从小白到大牛第1篇 Java基础—3042人已学习 课程介绍 本视频是智捷课堂推出的一套“Java语言学习立体教程”的视频第一部分&#xff0c;读者以及观看群是初级小白&#xff0c;通过本视频的学习能够成为Java大牛。本主要内容包括&#xff1a;Java语法基础、Java编码规范…