BRIEF描述子生成算法

简介: BRIEF描述子生成算法

一:介绍


我们知道SIFT算法通常通过对每个关键点生成128个特征向量作为描述子、SURF算法通常对关键点生成最少64个特征向量作为描述子。但是对于图像来说创建上千或者上万个这样的描述子内存开销比较大,运行速度受到严重影响。特别对嵌入式设备与一定设备来说,内存限制尤为明显,而且匹配的时候计算也比较耗时。



但是实际上这些特征数据OpenCV在匹配的时候并没有完全利用上,而是通过PCA、LDA等方法对它进行压缩,或者是LSH(局部敏感哈希)方法把这些特征描述子压缩从浮点数转换为二进制字符串,然后通过汉明距离(HammingDistance)进行比较。这样就可以通过简单的异或操作(OXR)与位值计算来加速实现对象特征匹配,对于SSE指令集的CPU这种方法可以大大加速。但是这种方法仍然需要首先计算描述子,然后使用LSH方法进行压缩,无法避免过度的内存开销。



而Brief方法可以直接通过关键点生成二进制字符串,跳过了中间描述子生成步骤,这样就大大减低了内存要求与计算开销。Brief方法主要思路是对每个关键点附件选择若干个像素点,将这些像素点的像素值组合成二进制字符串,然后使用该字符串作为该关键点的描述子。


此方法是在2010年提出来的。结果实验测试在选取256个点甚至128个点情况下对没有旋转对象识别率非常高而且速度比SURF还快。但是当对象有旋转时候由于Brief不能很好的支持旋转不变性识别,特别是当旋转角度超过30度以上,准确率会快速下降。



二:Brief描述子生成步骤


Brief描述子生成首先需要产生足够多的随机点对,然后根据随机点对坐标得到对应像素值,对所有点对进行二进制字符串拼接,拼接完成即生成了描述子。


第一步:选择关键点周围SxS大小正方形图像区块,进行高斯模糊。这样做的原因是需要降低图像随机噪声,OpenCV在完成Brief的时候考虑到效率问题并没有采用高斯模糊而是采用了基于积分图的盒子模糊方法。


第二步:选择n个像素点对,其中n的取值常见为256、此外还可以是128、512。每个点对比较像素值输出如下。


对N个点对完成操作最终得到了二进制字符串,表达如下:

三:方法

高斯模糊比较

通过实验对比高斯sigma参数在0~3之间准确率比较高,窗口大小取值在9x9取得比较好的模糊去噪效果。论文中实验结果图示如下:


随机点生成方法比较

对于随机生成点对的方法,论文中给出了五种随机方法与实验结果比较,五种方法描述如下:


图示如下:


对图像五个几何采样完成测试结果如下:


其中第二种方法比其他四种稍微有点优势,而最不好的方法则是第五种方法。

四:OpenCV中Biref描述子演示

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <iostream>
 
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;
 
int main(int argc, char** argv) {
  Mat img1 = imread("D:/tree.png", IMREAD_GRAYSCALE);
  Mat img2 = imread("D:/tree_in_scene.png", IMREAD_GRAYSCALE);
  Mat src = imread("D:/gloomyfish/14.png", IMREAD_GRAYSCALE);
  Mat src1 = imread("D:/gloomyfish/14.png");
  if (!img1.data || !img2.data) {
    printf("could not load images...\n");
    return -1;
  }
  imshow("box", img1);
  imshow("scene", img2);
 
  auto detector = FastFeatureDetector::create();
  vector<KeyPoint> keypoints_obj;
  vector<KeyPoint> keypoints_scene;
  detector->detect(img1, keypoints_obj, Mat());
  detector->detect(img2, keypoints_scene, Mat());
 
  auto descriptor = BriefDescriptorExtractor::create();
  Mat descriptor_obj, descriptor_scene;
  descriptor->compute(img1, keypoints_obj, descriptor_obj);
  descriptor->compute(img2, keypoints_scene, descriptor_scene);
 
  BFMatcher matcher(NORM_L2);
  vector<DMatch> matches;
  matcher.match(descriptor_obj, descriptor_scene, matches);
 
  Mat resultImg;
  drawMatches(img1, keypoints_obj, img2, keypoints_scene, matches, resultImg);
  imshow("Brief Descriptor Match Result", resultImg);
 
  waitKey(0);
  return 0;
}

运行结果

相关文章
|
6月前
|
机器学习/深度学习 运维 算法
大模型开发:描述一种用于异常检测的技术或算法。
LOF算法是一种无监督异常检测技术,通过比较数据点局部密度识别离群点。它计算每个点的局部离群因子得分,得分高则异常可能性大。主要步骤包括:距离度量、k近邻搜索、计算局部可达密度和LOF得分,然后设定阈值识别异常点。适用于入侵检测、故障检测等场景,Python中可使用scikit-learn库实现。
95 1
|
1月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
67 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
4月前
|
存储 算法 Java
Java面试题:解释JVM的内存结构,并描述堆、栈、方法区在内存结构中的角色和作用,Java中的多线程是如何实现的,Java垃圾回收机制的基本原理,并讨论常见的垃圾回收算法
Java面试题:解释JVM的内存结构,并描述堆、栈、方法区在内存结构中的角色和作用,Java中的多线程是如何实现的,Java垃圾回收机制的基本原理,并讨论常见的垃圾回收算法
63 0
|
5月前
|
存储 算法 测试技术
数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)
数据结构学习记录——树习题-Complete Binary Search Tree(题目描述、输入输出示例、数据结构的选择、核心算法、计算左子树的规模)
77 1
|
6月前
|
机器学习/深度学习 算法 数据可视化
【机器学习】描述K-means算法的步骤
【5月更文挑战第11天】【机器学习】描述K-means算法的步骤
|
5月前
|
存储 算法
数据结构学习记录——图应用实例-六度空间(题目描述、算法思路、伪代码及解读、图解)
数据结构学习记录——图应用实例-六度空间(题目描述、算法思路、伪代码及解读、图解)
55 0
|
5月前
|
存储 算法 安全
数据结构学习记录——图应用实例-拯救007(问题描述、解题思路、伪代码解读、C语言算法实现)
数据结构学习记录——图应用实例-拯救007(问题描述、解题思路、伪代码解读、C语言算法实现)
39 0
|
6月前
|
机器学习/深度学习 人工智能 算法
【AI 初识】描述遗传算法概念
【5月更文挑战第2天】【AI 初识】描述遗传算法概念
|
6月前
|
搜索推荐 算法 Python
用伪代码描述冒泡排序算法及其实现
用伪代码描述冒泡排序算法及其实现
563 0
|
6月前
|
人工智能 自然语言处理 算法
算法01-算法概念与描述
算法01-算法概念与描述