OpenCV用MSER提取特征区域,上文介绍了如何通过逐步水淹并创建分水岭,把图像分割成多个区域。最大稳定外部区域(MSER)算法也用相同的水淹类比,以便从图像中提取有意义的区域。创建这些区域时也使用逐步提高水位的方法,但是这次我们关注的是在水淹过程中的某段时间内,保持相对稳定的盆地。可以发现,这些区域对应着图像中某些物体的特殊部分。
如何实现
计算图像MSER的基础类是cv::MSER
。它是一个抽象接口,继承自cv::Feature2D
类。事实上,OpenCV中的所有特征检测类都是从这个类继承的。cv::MSER
类的实例可以通过create方法创建。我们在初始化时指定被检测区域的最小和最大尺寸,以便限制被检测特征的数量,调用方式如下:
// 基本的MSER检测器
cv::Ptr<cv::MSER> ptrMSER=
cv::MSER::create(5, // 局部检测时使用的增量值
200, // 允许的最小面积
2000); // 允许的最大面积
现在可以通过调用detectRegions方法来获得MSER,指定输入图像和一个相关的输出数据结构,代码如下所示:
// 点集的容器
std::vector<std::vector<cv::Point> > points;
// 矩形的容器
std::vector<cv::Rect> rects;
// 检测MSER特征
ptrMSER->detectRegions(image, points, rects);
检测结果放在两个容器中。第一个是区域的容器,每个区域用组成它的像素点表示;第二个是矩形的容器,每个矩形包围一个区域。为了呈现结果,创建一个空白图像,在图像上用不同的颜色显示检测到的区域(颜色是随机选择的)。用以下代码实现:
// 创建白色图像
cv::Mat output(image.size(), CV_8UC3);
output= cv::Scalar(255,255,255);
// OpenCV随机数生成器
cv::RNG rng;
// 针对每个检测到的特征区域,在彩色区域显示MSER
// 反向排序,先显示较大的MSER
for (std::vector<std::vector<cv::Point> >::reverse_iterator
it= points.rbegin();
it! = points.rend(); ++it) {
// 生成随机颜色
cv::Vec3b c(rng.uniform(0,254),
rng.uniform(0,254), rng.uniform(0,254));
// 针对MSER集合中的每个点
for (std::vector<cv::Point>::iterator itPts= it->begin();
itPts! = it->end(); ++itPts) {
// 不重写MSER的像素
if (output.at<cv::Vec3b>(*itPts)[0]==255) {
output.at<cv::Vec3b>(*itPts)= c;
}
}
}
注意,MSER会形成层叠区域。为了显示全部区域,如果一个较大区域内包含了较小的区域,就不能覆盖它。可以从下图中检测出MSER。
结果如下图所示。
图中没有显示全部区域,但是可以看出,通过这种方法能从图片中提取到一些有意义的区域(例如建筑物的窗户)。
酷客网相关文章:
评论前必须登录!
注册