https://blog.csdn.net/a664607530/article/details/79319156
MSER最稳定极值区域源码分析
最稳定极值区域介绍
如把灰度图看成高低起伏的地形图,其中灰度值看成海平面高度的话,MSER的作用就是在灰度图中找到符合条件的坑洼。条件为坑的最小高度,坑的大小,坑的倾斜程度,坑中如果已有小坑时大坑与小坑的变化率。
上图展示了几种不同的坑洼,根据最小高度,大小,倾斜程度这些条件的不同,选择的坑也就不同。
上图展示了最后一个条件,大坑套小坑的情况。根据条件的不同,选择也不同。
以上便是对坑的举例,MSER主要流程就三部分组成:
1.预处理数据
2.遍历灰度图
3.判断一个区域(坑洼)是否满足条件
简单来说,就如将水注入这个地形中。水遇到低处就往低处流,如果没有低处了,水位就会一点点增长,直至淹没整个地形。在之前预处理下数据,在水位提高时判断下是否满足条件。
那怎么判断一个ER是不是MSER呢?对于单通道图像来说主要有五个参数:delta, maxVariation, minDiversity, minArea, maxArea。其中minArea, maxArea代表区域的面积,如ID11的面积是3,ID10的面积是10。
而delta是为了计算variation。MSER的核心思想是要找到一块区域,能跟周围的有明显的变化。在MSER里,这个是通过variation定义的。打个比方,一个脸盆和一个水桶,脸盆底部是个ER,水桶的底部也是一个ER。但是脸盆的底部跟边缘的高度相差不大,我只要把水位增加一点,水就溢出来,脸盆的边缘和底部合成了一个新的ER。但如果是水桶,你需要加很多水才能行成新的ER。因此水桶的ER更稳定,它跟周围的对比度更强。一个定义是:
其中S代表的ER的面积,在Opencv中简化为:
比如delta = 2, 要计算ID1的vatiation, 可以看出S(ERlevel) = 9, ID1的gray level是3,因此要找到3 - 2 = 1 gray level的ER, 我们去点数最多的,都是1,因此按照上面的公式是(9 - 1) / 1,variation是8。还有个限制是当前ER的variation要小于父和子的variation。
minDiversity是为了解决两个MSER靠的很近的问题。公式如下,MSERson代表的是子节点最近的已经确认是MSER的区域。如果有个子MSER,而且两个点数比较接近,我们认为两个ER相隔太近,父的ER就不能当成MSER。
opencv代码分析:
下面分析minDiversity是为了解决两个MSER靠的很近的问题。
float div = (float)(comp->history->size - comp->history->stable) / (float)comp->history->size;
int stable = (dvar && !comp->dvar && comp->var < params.maxVariation && div > params.minDiversity);
例: comp->history->size = 60;comp->history->stable = 59。
60 - 59 / 60 很小,靠的近时,div 值很小。和stable靠的近时,值很小。靠的远时,div大。params.minDiversity 设置小的,就能让靠的近点的。合并为可靠区域。
MSER的核心思想是要找到一块区域,能跟周围的有明显的变化
return (float)(comp->size - shortcut->size) / (float)shortcut->size;
这个返回值也大变小。comp->size和shortcut->size会比较靠近。趋向于0。
static bool MSERStableCheck(MSERConnectedComp* comp, MSERParams params)
{
if (stable)
// 如果稳定的话,稳定值就是像素数
comp->history->stable = comp->history->size; //ll 记录的稳定区域的。 comp->size 是不记录的。所以需要
//ll 稳定区域在水平上涨后,的区域加判断。
}
comp->size 674 int
params.maxVariation 0.050000000745058060 double
comp->history->stable 664 int