1.图像搜索,以图搜图。
2.拼图游戏。
3.图像拼接,将两张有关联的图拼接在一起。
图像特征就是指有意义的图像区域,具有独特性、易于识别性,比如角点、斑点以及高密度区。
从上图我们可以发现:
A、B两图我们很难找到具体定位;
C、D两图可以找到一些相似区域,但不太容易确定;
E、F两图则很容易确定其定位,即特征信息丰富。
由此,我们可以知道角点是非常重要的特征信息。
(1)在特征中最重要的是角点;
(2)灰度梯度的最大值对应的像素点;
(3)两条线的交点;
(4)极值点(一阶导数最大值,但二阶导数为0)。
Harris角点检测API
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)
Shi-Tomasi角点检测API
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)
图1 原图 图2 Harris角点检测 图3 Shi-Tomasi角点检测
SIFT出现的原因
使用SIFT的步骤
计算描述子
同时计算关键点和描述子的API
SURF的优点
使用SURF的步骤
ORB的优点
BRIEF 对已经检测到的特征点进行描述,加快了特征点描述符建立的速度,同时也极大的降低了特征匹配的时间
使用ORB的步骤
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特征检测
暴力特征匹配方法的原理(枚举)
openCV特征匹配的步骤
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)
FLANN优缺点
使用FLANN特征匹配的步骤
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)
图1 BF暴力特征匹配 图2 FLANN特征匹配
注:内容来自慕课网李超老师的视频课程整理。