一、应用场景

        1.图像搜索,以图搜图。

        2.拼图游戏。

        3.图像拼接,将两张有关联的图拼接在一起。

二、基础概念

2.1 什么是图像特征?

        图像特征就是指有意义的图像区域,具有独特性、易于识别性,比如角点、斑点以及高密度区。

         从上图我们可以发现:

        A、B两图我们很难找到具体定位;

        C、D两图可以找到一些相似区域,但不太容易确定;

        E、F两图则很容易确定其定位,即特征信息丰富。

        由此,我们可以知道角点是非常重要的特征信息。

2.2 角点

        (1)在特征中最重要的是角点;

        (2)灰度梯度的最大值对应的像素点;

        (3)两条线的交点;

        (4)极值点(一阶导数最大值,但二阶导数为0)。

三、特征检测

3.1 角点检测

3.1.1 Harris角点检测

光滑地区,无论向哪个移动,衡量系数不变边缘地区,垂直边缘移动时,衡量系统剧烈变化在交点处,往那个方向移动,衡量系统都发生剧烈变化

    Harris角点检测API

cornerHarrris(img,dst,blockSize,ksize,k)blockSize: 检测窗口大小ksize: Sobel的卷积核k 权重系数,经验值,一般取0.02-0.04之间

import cv2

import numpy as np

# 读取图片

img = cv2.imread('./chess.png')

# 灰度化

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Harris角点检测

dst = cv2.cornerHarris(gray, blockSize=2, ksize=3, k=0.04)

# Harris角点的展示

img[dst > 0.01*dst.max()] = (0, 0, 255)

cv2.imshow('Harris', img)

cv2.waitKey(0)

3.1.2 Shi-Tomasi角点检测

shi- tomasi是Harris角点检测的改进Harris角点检测算的稳定性和k有关,而k是个经验值,不好设定最佳值

   Shi-Tomasi角点检测API

goodFeaturesToTrack(img,maxCorners,…)maxCorners:角点的最大数,值为0表示无限制qualityLevel:小于1.0的正数,一般在0.01-0.1之间minDistance:角之间最小欧式距离,忽略小于此距离的点mask: 感兴趣的区域blockSize:检测窗口useHarrisDectector:是否使用Harris算法k :默认是0.04

import cv2

import numpy as np

img = cv2.imread('./chess.png')

# 灰度化

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 角点检测

corners = cv2.goodFeaturesToTrack(gray, maxCorners=1000, qualityLevel=0.01, minDistance=10,)

corners = np.int0(corners)

# Shi-Tomasi绘制角点

for i in corners:

x,y = i.ravel()

cv2.circle(img, (x,y), 3, (0,0,255),-1)

cv2.imshow('Shi-Tomasi', img)

cv2.waitKey(0)

3.1.3 检测效果展

   

                          图1 原图                                                   图2 Harris角点检测                                      图3  Shi-Tomasi角点检测

3.2关键点与描述子

关键点:位置,大小和方向关键点描述子:记录了关键点周围对其有贡献的像素点的一组向量值,其不受仿射变换、光照变换等的影响

3.2.1 SIFT(Scale-Invariant Feature Transfrom)特征检测

   SIFT出现的原因

Harris 角点具有旋转不变的特性,但缩放后,原来的角点有可能就不是角点了,如下图所示:

   使用SIFT的步骤

创建SIFT对象,sift = cv2.SIFT_create()进行检测,kp = sift.detect(img,…)绘制关键点,drawKeypoints(gray, kp, img)

  计算描述子

kp,des=sift.compute(img,kp)其作用就是进行特征匹配

   同时计算关键点和描述子的API

kp,des=sift.detectAndCompute(img,…)mask:指明对img中哪个区域进行计算

3.2.2 SURF(Speeded-Up Robust Features)特征检测

  SURF的优点 

SIFT最大的问题就是速度慢,因此才有SURF

  使用SURF的步骤

surf = cv2.xfeatures2d.SURF_create()kp, des = surf.detectAndCompute(img, mask)

3.2.3 ORB(Orirnted FAST and Rotated BRIEF)特征检测

  ORB的优点 

可以实现实时检测ORB = Orirnted FAST + Rotated BRIEF,即是两种技术的结合FAST 可以做到特征点的实时检测 BRIEF 对已经检测到的特征点进行描述,加快了特征点描述符建立的速度,同时也极大的降低了特征匹配的时间

  使用ORB的步骤

orb = cv2.ORB_create()kp,des =orb.detectAndCompute(img,mask)

3.2.4 代码及检测效果

import cv2

import numpy as np

# 读文件

img = cv2.imread('chess.png')

# 灰度化

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 创建sift对象,进行检测

sift = cv2.SIFT_create()

kp,des = sift.detectAndCompute(gray, None)

# 创建SURF对象,进行检测

# surf = cv2.xfeatures2d.SURF_create()

# kp,des = surf.detectAndCompute(gray, None)

# 创建ORB对象,进行检测

# orb = cv2.ORB_create()

# kp,des = orb.detectAndCompute(gray, None)

# print(des)

# 绘制keypoints

cv2.drawKeypoints(gray, kp, img)

cv2.imshow('img', img)

cv2.waitKey(0)

                             图1 原图                                                    图2 SIFT特征检测                                        图3  ORB特征检测

四、特征匹配

4.1 BF(Brute-Force)暴力特征匹配方法

  暴力特征匹配方法的原理(枚举)

它使用第一组中的每个特征的描述子,与第二组中的所有特征描述子进行匹配计算他们之间的差距,然后将最接近一个匹配返回(也即计算他们之间的相似度)

  openCV特征匹配的步骤

创建匹配器,BFMatcher(normType, crossCheck)进行特征匹配,bf.match(des1,des2)绘制匹配点,cv2.drawMatches(img1,kp1,img2,k2)

import cv2

import numpy as np

# 读取图片

img1 = cv2.imread('2.jpg')

img2 = cv2.imread('1.jpg')

# # 灰度化

gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)

gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)

# 检测特征点+描述子

sift = cv2.SIFT_create() # 创建SIFT对象

kp1, des1 = sift.detectAndCompute(gray1, None) # 对整个图像进行检测,掩码设为None

kp2, des2 = sift.detectAndCompute(gray2, None) # 对整个图像进行检测,掩码设为None

# 创建匹配器

bf = cv2.BFMatcher(cv2.NORM_L1)

match = bf.match(des1, des2) # 获得匹配点

res = cv2.drawMatches(img1, kp1, img2, kp2, match, None) # 绘制匹配点

# cv.drawKeypoints(gray, kp, img) # 绘制特征点

# # 显示图像

cv2.imshow('BF', res)

cv2.waitKey(0)

4.2 FLANN最快邻近区特征匹配方法

   FLANN优缺点

在进行批量特征匹配时,FLANN速度更快由于它使用的是邻近近似值,所以精度较差

  使用FLANN特征匹配的步骤

创建FLANN匹配器,FlannBasedMatcher(…)进行特征匹配,flann.match/knnMatch(…)绘制匹配点,cv.drawMatches/drawMatchesKnn(…)

import cv2

import numpy as np

# 读取图片

img1 = cv2.imread('2.jpg')

img2 = cv2.imread('1.jpg')

# 灰度化

gray1 = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)

gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)

# 创建sift特征匹配器

sift = cv2.SIFT_create()

# 计算描述子与特征点

kp1, des1 = sift.detectAndCompute(gray1, None)

kp2, des2 = sift.detectAndCompute(gray2, None)

# 创建匹配器

index_params = dict(algorithm=1, trees=5)

search_params = dict(checks=50)

flann = cv2.FlannBasedMatcher(index_params, search_params)

# 对描述子进行匹配

matches = flann.knnMatch(des1, des2, k=2)

good = []

for i, (m, n) in enumerate(matches):

if m.distance < 0.7*n.distance:

good.append(m)

# 绘制匹配点

ret = cv2.drawMatchesKnn(img1,kp1,img2,kp2,[good],None)

cv2.imshow('FLANN', ret)

cv2.waitKey(0)

 4.3 特征匹配效果图

 

                                             图1 BF暴力特征匹配                                                                 图2 FLANN特征匹配

注:内容来自慕课网李超老师的视频课程整理。

推荐链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: