• BRIEF算法


    本文结构

    为了看懂ORB特征提取算法,来看了BRIEF算法的原文,并查看了OpenCV中BRIEF的相关实现,来验证论文的解读正确与否。

    BRIEF论文解读

    摘要

    用二进制串描述局部特征,好处有二:一是很少的bit就能描述独特的性质;二是可以用汉明距离计算两个二进制串之间的特征,计算速度快。在实际应用中的好处是:算的准;算的快;省内存

    BRIEF特征的建立和用于匹配,都很快。性能测试表明,BRIEF比SURF和U-SURF快,准确度差不多。

    Introduction

    经验表明,用256甚至128个bit表示一个BRIEF特征就够用了。算的快,省内存,适合实时计算的应用,比如SLAM(省计算)或者三维重建(省存储)。
    先前一些算法,先计算浮点型特征描述向量,再转化为二进制表示。这样的算法,匹配很快,但是前期还是慢。
    BRIEF是在keypoint周边随机取点对进行灰度计算,直接得到二进制特征描述向量。

    Method

    图像patch先做平滑操作,再根据检验结果(response of test,比如t检验,即t-test)生成二进制描述符。
    创建这样的特征向量,需要考虑的是高斯模糊的模糊核kernel(即(sigma))值的选取,以及点对((vecx_1, vecx_2))的选取,其中(vec x_1=(u,v)^T)_
    模糊的作用是消噪。

    识别率的实验表明,sigma取2的效果最好,对应的高斯窗口为9x9规格。
    论文提出了5种选择[x,y]的方式,并根据识别率进行实验,发现第二种性能最好:(X, Y) ∼ i.i.d. Gaussian(0, (1/25)S^2)
    注意:这里的高斯分布容易引起混淆,详细讲是:每次t-检验中,要选取的两个点为(X,Y),其中X=(u1,v1)^T,Y=(u2,v2)^T,(X,Y)~N(0, (1/25)S^2)
    实际测试发现sigma^2=(1/25)S^2能有最高的识别率。

    我还是不明白,空域中到底要怎么选点?
    看了OpenCV中的实现发现,所谓随机选点,只是最开始的一个patch是随机选点,并且这个选出来的点的顺序要记录下来给后面所有的patch使用。并且,这些选出的点并不是真正的、纯粹的随机,而是服从上述高斯分布的。

    为什么patch在t-检验前要做平滑?
    因为论文原文提出的t-检验,每次检查的是两个像素点。单个像素点是噪声敏感的。因此要做平滑操作。(而平滑操作比较耗时,这也为后来的优化做了伏笔。Calonder等人又于2011年提出采用盒状滤波器的处理方法来代替高斯平滑处理方法)

    实验和结果

    在6种图片上,分别使用SURF、U-SURF、BRIEF-16、BRIEF-32、BRIEF-64进行测试,发现BRIEF-32除了在涂鸦(Graffitti)上表现不如SURF和U-SURF好之外,其他图片序列上基本都是最好的。而且显然BRIEF-32也和BRIEF-64差不了太多,并且也基本胜过SURF和U-SURF。

    上述比较过程中,keypoint是用的SURF的keypoint。实际上SURF的keypoint会吃掉BRIEF带来的速度提升,一般用其他更快的keypoint检测子,比如CenSurE(Center Surround Extremas Realtime Feature Detector and Matching这篇论文提出。也可以考虑FAST等算法,FAST:Rosten, E., Drummond, T.: Machine Learning for High-Speed Corner Detection. In: European Conference on Computer Vision)。但是,换用了更快的检测子,能保证识别率吗?
    同样的测试图片,对比分别用SURF和CenSurE检测的keypoint然后接上BREIF描述符,测量匹配的准确度,CenSurE在大多数情况下比SURF准确率还高;个别情况稍低于SURF。

    旋转角的讨论

    BRIEF没有专门考虑旋转的问题。那么就从0°~360°进行旋转测试吧。
    发现小范围(0-15°)内,BRIEF识别率最高,其次是U-SURF,然后是SURF和o-BRIEF;
    角度再大一点(15°~30°),BRIEF和U-SURF准确率迅速下降到0,角度再大,则这两个算法的识别率保持为0.而SURF和o-BRIEF这两个考虑旋转方向的算法,始终能保持大于60%的准确率,而且在90°的倍数角度处,识别率有极大值。

    这里的o-BRIEF是:用SURF算出旋转角度,然后用BRIEF按照这个角度旋转再进行描述的一个算法。
    这里的BRIEF都是BRIEF-32。
    o-BRIEF和SURF的识别率,在旋转角度从0到180度变化时,几乎是重合的。

    实验中还测量了SURF和BRIEF在description和matching两个阶段的对比,发现特征描述的计算时间上相差35-40倍,精确邻近匹配的计算时间上相差3~10倍。
    通常U-SURF比SURF快上3倍左右。

    当前BRIEF的大多数时间消耗在高斯模糊操作上。基于积分图像的近似平滑操作,能加速。

    结论

    BRIEF算的快(二进制描述,汉明距离匹配),算的准(这很重要),省内存(远少于SIFT和SURF的描述符位数)。
    下一步考虑方向和尺度。使用快速的方向估测子(fast orientation estimators),没理由不相信速度不快!

    OpenCV中的实现

    对一个keypoint(及其所在区域,称为patch),在生成其描述符之前,BRIEF要先对patch做高斯平滑,这会消耗时间。
    OpenCV在具体的实现上,结合了平滑和积分图像的思想,将t-检验中原本的两个点p1、p2,替换成p1、p2各自一个模板区域内的像素之和,这个模板区域以p1或p2为左上角定点。也就是,从原来的单独两个点的像素值比较,换成了两个模板区域内的像素和的比较,参与比较的点多了,降低了噪声的影响。但是计算效率呢?没关系,因为使用了积分图像,因此计算时间是O(4)=O(1)的:

    inline int smoothedSum(const Mat& sum, const KeyPoint& pt, int y, int x)
    {
        static const int HALF_KERNEL = BriefDescriptorExtractor::KERNEL_SIZE / 2;
    
        int img_y = (int)(pt.pt.y + 0.5) + y;
        int img_x = (int)(pt.pt.x + 0.5) + x;
        return   sum.at<int>(img_y + HALF_KERNEL + 1, img_x + HALF_KERNEL + 1)
               - sum.at<int>(img_y + HALF_KERNEL + 1, img_x - HALF_KERNEL)
               - sum.at<int>(img_y - HALF_KERNEL, img_x + HALF_KERNEL + 1)
               + sum.at<int>(img_y - HALF_KERNEL, img_x - HALF_KERNEL);
    }                                                                         
    

    这里的积分图像的使用,其实也就是盒状滤波器:指定区域内的像素和,或者像素和的归一化结果;也就是一个元素全为1,再乘以一个系数的矩阵。
    当然,盒状滤波器在实现的过程中可以有更快的实现方式,即分别指定一维的行内滤波器和列内滤波器,每个滤波器都是计算整个行或列的元素和:先逐列扫描,每列计算元素和,并存储到临时数组中;再对临时数组使用行滤波器进行求和,这样就得到一个区域的盒状滤波结果了。

    参考:
    Opencv2.4.9源码分析——BRIEF
    极限优化:Haar特征的另一种的快速计算方法—boxfilter

  • 相关阅读:
    关于spring的applicationContext.xml配置文件的ref和value之自我想法
    解决kindeidtor与struts2框架交互WARN OgnlValueStack:68
    使用JavaMail发送邮件,465端口开启ssl加密传输
    springData 整合 Rrdis
    org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter cannot be cast to javax.servlet.Filter
    Unable to locate parent package [json-default]
    ASP.NET 在请求中检测到包含潜在危险的数据,因为它可能包括 HTML 标记或脚本
    jquery不能实时获取CKEDITOR值的解决方法
    UltraEdit窗口布局重新设置
    C# sqlserver ExecuteNonQuery()方法详解
  • 原文地址:https://www.cnblogs.com/zjutzz/p/4986455.html
Copyright © 2020-2023  润新知