Selective Search
论文及算法解析
Efficient Graph-Based Image Segmentation
- 在实现Selective Search前,我们先需要了解Efficient Graph-Based Image Segmentation。
论文及算法解析
具体实现步骤
第一步生成一个和图片相同大小的画布二维数组S,上面每一个独立的像素点都有自己的编号。
每个像素点都标记为初始的小区域,把它的编号赋给区域,维护一个区域数组容器。
计算每单个像素点向周围四方向或八方向的颜色梯度。
把每两个像素点实现的“边”的颜色梯度大小进行从小到大排序。
从第一个边开始遍历,计算这两个像素点代表的区域是否进行合并,若进行合并则在画布上记录并把比较小的区域标记为“死亡”,然后把较大区域的类内差异和大小等信息更新;若不进行合并则把这条边放入另一个独立容器。
此时,基本的合并已经完成,现在以颜色梯度从小到大排序放入了未进行合并操作的边的容器,并遍历该容器,若边的两个像素点代表的区域均“存活”,且其中的一个区域的大小低于m(预设值)个像素点,则进行合并且在画布上记录并把比较小的区域标记为“死亡”,然后把较大区域的类内差异和大小等信息更新。
返回画布S。
具体实现步骤
第一步初始化生成小区域,使用Efficient Graph-Based Image Segmentation过度分割生成小区域,取得带有结果的二维数组。(最小区域像素值可为30)
读取二维数组的数据,并把区域编号重新标记,并且读取每个区域的颜色,纹理,大小,位置,附近的区域编号等数据,把区域放入一个容器S。
遍历容器S,用Set容器R存放装有两个相邻区域的反差异值(用hashcode保证没有相同的数据存入)和相邻区域编号等数据的对象。按照反差异值从大到小排序。
重复下列步骤,直到容器S为空:
1.从容器R中取出第一个对象,合并该对象指向的两个区域。把比较小的区域a标记为“死亡”,更新比较大的区域b的数据。
2.遍历容器R,剔除包括过以上两个区域a,b的对象。
3.遍历容器S,把标记了”死亡”的区域a从每个区域附近的区域编号中剔除。
4.计算区域b与它附近的区域的反差异值,把内容放入装有容器R。
5.把容器R里的对象按照反差异值从大到小排序。返回容器S。
代码实现
网上已经有了C++,matlab和python版的了,正好这学期学JAVA,就写了个JAVA版的,希望能够帮助大家理解。
结果
总结
- Selective Search在RCNN和Fast RCNN上取得了不错的效果,但区域检测的速度太慢了。目前主流的神经网络模型,如RCNN Fatser,YOLOv2均把区域检测放在卷积后的网络中,利用Bounding Box Regression回归成需要的形状,这样一来需要识别的维度大大减小,速度大幅增加,可以实时训练、得出结果。