数据可视化CV

OpenCV+Python特征提取算法与图像描述符之SIFT /

2018-10-12  本文已影响445人  音符纸飞机
有许多用于特征检测和提取的算法,我们将会对其中大部分进行介绍。OpenCV最常使用的特征检测和提取算法有:
通过以下方法进行特征匹配:
特征提取算法比较

算法效果比较博文

基本概念

特征向量

用于表示和量化图像的数字列表,简单理解成将图片转化为一个数字列表表示。特征向量中用来描述图片的各种属性的向量称为特征矢量。

特征描述符(特征描述子)Descriptor

参考
是一种算法和方法,输入1个图像,返回多个特征向量(主要用来处理图像的局部,往往会把多个特征向量组成一个一维的向量)。主要用于图像匹配(视觉检测),匹配图像中的物品。

SIFT特征算法与DoG尺度空间

SIFT论文
原理
opencv官网解释
实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。SIFT所查找到的关键点是一些十分突出,不会因光照,仿射变换和噪音等因素而变化的点,如角点、边缘点、暗区的亮点及亮区的暗点等。

SIFT

尺度不变特征转换(Scale-invariant feature transform或SIFT)是一种电脑视觉的算法用来侦测与描述影像中的局部性特征,它在空间尺度中寻找极值点,并提取出其位置、尺度、旋转不变量。
其应用范围包含物体辨识、机器人地图感知与导航、影像缝合、3D模型建立、手势辨识、影像追踪和动作比对。

尺度空间

对现实中物体的描述一定要在一个十分重要的前提下进行,这个前提就是对自然界建模时的尺度。当用一个机器视觉系统分析未知场景时,计算机没有办法预先知道图像中物体的尺度,因此我们需要同时考虑图像在多尺度下的描述,获知感兴趣物体的最佳尺度。图像的尺度空间表达指的是图像的所有尺度下的描述。

SIFT算法分解为如下四步:
  1. 尺度空间极值检测:搜索所有尺度上的图像位置。通过高斯微分函数来识别潜在的对于尺度和旋转不变的兴趣点。
  2. 关键点定位:在每个候选的位置上,通过一个拟合精细的模型来确定位置和尺度。关键点的选择依据于它们的稳定程度。
  3. 方向确定:基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向。所有后面的对图像数据的操作都相对于关键点的方向、尺度和位置进行变换,从而提供对于这些变换的不变性。
  4. 关键点描述:在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度被变换成一种表示,这种表示允许比较大的局部形状的变形和光照变化。
sift = cv2.xfeatures2d.SIFT_create()
'''
SIFT_create([, nfeatures[, nOctaveLayers[, contrastThreshold[, edgeThreshold[, sigma]]]]]) -> retval
    .   @param nfeatures The number of best features to retain. The features are ranked by their scores
    .   (measured in SIFT algorithm as the local contrast)
    .   
    .   @param nOctaveLayers The number of layers in each octave. 3 is the value used in D. Lowe paper. The
    .   number of octaves is computed automatically from the image resolution.
    .   
    .   @param contrastThreshold The contrast threshold used to filter out weak features in semi-uniform
    .   (low-contrast) regions. The larger the threshold, the less features are produced by the detector.
    .   
    .   @param edgeThreshold The threshold used to filter out edge-like features. Note that the its meaning
    .   is different from the contrastThreshold, i.e. the larger the edgeThreshold, the less features are
    .   filtered out (more features are retained).
    .   
    .   @param sigma The sigma of the Gaussian applied to the input image at the octave \#0. If your image
    .   is captured with a weak camera with soft lenses, you might want to reduce the number.
'''
keypoints, descriptor = sift.detectAndCompute(img_gray, None)
'''
        detectAndCompute(image, mask[, descriptors[, useProvidedKeypoints]]) -> keypoints, descriptors
        .   Detects keypoints and computes the descriptors
        算法分成了两步,第一步特征提取,第二步计算描述符
'''

'''
keypoints数据结构
pt, 坐标
size, 特征直径
angle, 特征方向
response, 特征强度
octave,该特征在金字塔的第几层被找到
class_id
'''

KeyPoint数据结构解析

img = cv2.imread('laugh.jpg')
img_large = cv2.imread('laugh_large.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_large = cv2.cvtColor(img_large, cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create()
keypoints, descriptor = sift.detectAndCompute(gray, None)
keypoints2, descriptor2 = sift.detectAndCompute(gray_large, None)
img = cv2.drawKeypoints(image=img, outImage=img, keypoints=keypoints, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
                        color=(0, 0, 255))
img_large = cv2.drawKeypoints(image=img_large, outImage=img_large, keypoints=keypoints2,
                              flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
                              color=(0, 0, 255))

cv2.imshow('sift', img)
cv2.imshow('sift_large', img_large)
SIFT效果

SURF算法和Fast Hessian矩阵

SURF论文
原理
opencv官网解释
SURF是SIFT的加速版,它善于处理具有模糊和旋转的图像,但是不善于处理视角变化和光照变化。在SIFT中使用DoG对LoG进行近似,而在SURF中使用盒子滤波器对LoG进行近似,这样就可以使用积分图像了(计算图像中某个窗口内所有像素和时,计算量的大小与窗口大小无关)。总之,SURF最大的特点在于采用了Haar特征以及积分图像的概念,大大加快了程序的运行效率。

surf = cv2.xfeatures2d.SURF_create(hessian_threshold)
# hessian_threshold 保留的特征值越少,越强大的特征值才会被保留,需要根据具体图像进行调整
img = cv2.imread("laugh.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

alg = cv2.xfeatures2d.SURF_create(10000)
keypoints, descriptor = alg.detectAndCompute(gray, None)
img = cv2.drawKeypoints(img, keypoints, img, (0, 0, 255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

cv2.imshow('hessian_10000', img)
SURF - hessan阈值效果对比
SURF - 不同尺度效果对比
注意事项

因为专利原因,OpenCV3.3开始不再免费开放SIFT\SURF,需要免费的请使用ORB算法

ORB特征算法

ORB算法综合了FAST角点检测算法和BRIEFF描述符。

FAST特征检测

算法原理
opencv官方文档
FAST只是一种特征点检测算法,并不涉及特征点的特征描述。

fast = cv2.FastFeatureDetector_create(threshold=10)
img = cv2.imread("laugh.jpg", 0)
fast = cv2.FastFeatureDetector_create()
keypoints = fast.detect(img, None)
img = cv2.drawKeypoints(img, keypoints, None, (0, 0, 255))
FAST - threshold100效果图 FAST - 默认threshold(10)效果图
BRIEF特征描述符

论文
opencv官方文档
中文版
Brief是Binary Robust Independent Elementary Features的缩写。这个特征描述子是由EPFL的Calonder在ECCV2010上提出的。主要思路就是在特征点附近随机选取若干点对,将这些点对的灰度值的大小,组合成一个二进制串,并将这个二进制串作为该特征点的特征描述子。文章同样提到,在此之前,需要选取合适的gaussian kernel对图像做平滑处理。

缺点

1:不具备旋转不变性。
2:对噪声敏感
3:不具备尺度不变性。

img = cv2.imread("laugh.jpg", 0)
# Initiate FAST detector
star = cv2.xfeatures2d.StarDetector_create()
# Initiate BRIEF extractor
brief = cv2.xfeatures2d.BriefDescriptorExtractor_create()
# find the keypoints with STAR
kp = star.detect(img, None)
# compute the descriptors with BRIEF
kp, des = brief.compute(img, kp)
print(brief.descriptorSize())
print(des.shape)

ORB

ORB论文
OpenCV官方文档

ORB采用了FAST作为特征点检测算子,特征点的主方向是通过矩(moment)计算而来解决了BRIEF不具备旋转不变性的问题。
ORB还做了这样的改进,不再使用pixel-pair,而是使用9×9的patch-pair,也就是说,对比patch的像素值之和,解决了BRIEF对噪声敏感的问题。
关于计算速度:
ORB是sift的100倍,是surf的10倍。

import cv2

img = cv2.imread("A.jpg", 0)
orb = cv2.ORB_create()
kp, des = orb.detectAndCompute(img, None)
# len(kp) : 485
# des.shape:  (485, 32)
ORB效果
上一篇 下一篇

猜你喜欢

热点阅读