OpenCV用MSER提取特征区域

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。
OpenCV用MSER提取特征区域

结果如下图所示。
OpenCV用MSER提取特征区域

图中没有显示全部区域,但是可以看出,通过这种方法能从图片中提取到一些有意义的区域(例如建筑物的窗户)。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!