Camera系列文章
传感器融合是将多个传感器采集的数据进行融合处理,以更好感知周围环境;这里首先介绍Camera的相关内容,包括摄像头及图像知识基本介绍,OpenCV图像识别(特征提取,目标分类等),融合激光点云和图像进行TTC估计。
系列文章目录
1. 摄像头基础及校准
2. Lidar TTC估计
3. Camera TTC估计
4. OpenCV图像特征提取
5. 常见特征检测算法介绍
6. 常见特征描述符介绍
7. YOLOv3物体检测
文章目录
前言
Descriptor描述符提供特征点Keypoint周围的独特信息。本章将介绍基于梯度的描述符和二进制描述符的差异,以及计算速度的优势。
- 基于梯度的描述符的的代表:Scale Invariant Feature Transform (SIFT);
- 二进制描述符代表:Binary Robust Invariant Scalable Keypoints (BRISK)
HOG描述符
为计算与前车的TTC,我们需要检出并跟踪连续帧中的特征点Keypoint。因此需要根据特征点的相似度(描述符)匹配前后帧的特征点以实现追踪。
下面我们重新对这些术语进行描述。
- 特征点检测算子(keypoint detector):基于局部极大值选择图像特征点的算法;
- 描述符(descriptor):一个描述特征点周围图块的向量值,有很多相关的方法,从简单的对比像素值,到复杂的HOG梯度直方图(Histogram of Oriented Gradients),基于梯度来计算直方图;HOG所得到的特征描述符能够为特征匹配和目标检测提供非常重要的信息。
描述符用于匹配连续帧中相似的特征点,如下图所示,这些特征点代表同一物体。为最大化相似度,一个好的算子应该要最小化可能的错误匹配。
HOG描述符的基本思路是根据强度梯度的分布描述局部区域的物体结构,他将图像划分成一定大小的单元,计算其梯度分布,这些梯度分布图可作为相似度度量来识别特征点。
SIFT尺度不变特征变换 (Scale-Invariant Feature Transform)
HOG描述符中最具代表的是尺度不变特征变换(SIFT,Scale-Invariant Feature Transform),SIFT方法同时包括特征点检测算法和描述符,有以下步骤:
- 使用"Laplacian-Of-Gaussian (LoG)"方法基于强度二次微分检测图像中的特征点,LOG适用于不同尺度的图像,倾向于检出斑点而不是角点。除了不同尺度,特征点也包含特征点方向。
- 对于每个特征点,通过去除方向保证canonical orientation。另外,区域缩放成16×16的像素,提供归一化的图块。
- 基于强度梯度 I x I_x Ix I y I_y Iy计算以上归一化图块的方向和幅度;
- 将以上归一化的图块分成4×4单元,每个单元中超过一定幅度的像素特征纳入8个方向的直方图中。
- 16个单元,8个方向的梯度直方图级联成128大小的向量,作为描述符,用来描述特征点。
SIFT检测算法/描述符可以考考识别物体,即使杂乱无章及部分遮挡。对于尺寸变化,旋转,亮度和对比度变化,甚至仿射失真也局部鲁棒性。
SIFT的确定是计算速度低,影响其在手机等的实时应用中。
其他HOG描述符(如SURF,GLOH),计算速度得到优化,然后,计算速度依然相对较慢。
二进制描述符
HOG类型的描述符主要问题是需要计算强度梯度,计算量大;这也是为什么SIFT通常不会用在手机上算力有限的设备上。尽管SURF算法导入后有一定的进步,但依然很少看到其在实时设备上应用。
二进制描述符的核心思想是,只依赖于强度信息,将特征点周围信息编码至一组二进制数字,在匹配阶段可以有效地进行对比搜索。目前最有名的二进制描述符是BRIEF,BRISK,ORB, FREAK,KAZE(都可以在OpenCV库中找到)。
二进制描述符主要包含三部分:
- 采样模型Sampling Pattern:描述Keypoints特征点附近采样点位置。
- 角度补偿算法,消除特征点周围图像块的旋转的影响。
- 采样点配对,根据强度值对比进行采样点配对。
Binary Robust Invariant Scalable Keypoints (BRISK)
BRISK的特征点检测算法/描述符是二进制描述符的典型代表,2011年Stefan Leutenegge提出,基于FAST检测算法和通过对每个特征点周围进行特定方法采样后进行强度对比的二进制描述符。
BRISK采样模型由一系列采样点(绿色)和相应的用于高斯平滑滤波的红色同心圆组成。BRISK的采样模型是固定的,高斯平滑滤波可以避免混叠效应。
#include <iostream>
#include <numeric>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>
using namespace std;
void descKeypoints1()
{
// load image from file and convert to grayscale
cv::Mat imgGray;
cv::Mat img = cv::imread("../images/img1.png");
cv::cvtColor(img, imgGray, cv::COLOR_BGR2GRAY);
// BRISK detector / descriptor
cv