计算机视觉作业
SIFT,即尺度不变特征变换(Scale-invariant feature transform,SIFT),是用于图像处理领域的一种描述。这种描述具有尺度不变性,可在图像中检测出关键点,是一种局部特征描述子。
特征检测步骤:
SIFT特征描述大概可以归纳为三步骤:
1)高斯差分金字塔的构建;
2)特征点定位及搜索;
3)特征描述
步骤1:高斯差分金字塔的构建(Difference of Gaussian:DOG)
➢ 利用高斯核对图像做卷积运算
➢ 根据不同的高斯核参数生成不同尺度结果,高斯金字塔(DOG)
步骤2:特征点定位及搜索
➢ 搜索:在任意像素局部相邻的两个DOG层中,搜索出卷积最大及最小点,例如在
3×3×3立方体范围内搜索。
➢ 定位:搜索到初始位置后,再利用泰勒展开式,采用曲线拟合策略对关键点进行
精确定位
步骤3:特征描述(方向赋值及特征描述)
➢ 方向赋值 :利用梯度方向直方图计算出关键点主方向
➢ 关键点的特征描述:
1、对于一个关键点,先将坐标轴旋转到关键点的主方向 (旋转不变性) 。
2、以关键点为中心,取16×16邻域,划分16个4×4的子区域,对每个子区域统计8个梯度方向,每个值都是描述子的一个维度。
3、关键点描述子共有128维(8×4×4)。
附代码:
import cv2
import numpy as np
# Sift operator is used to describe features and used for image alignment.
img1 = cv2.imread('img5_2.jpg')
img2 = cv2.imread('img5_1.jpg')
img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
sift = cv2.SIFT_create()
kp1, dp1 = sift.detectAndCompute(img1_gray, None)
kp2, dp2 = sift.detectAndCompute(img2_gray, None)
#matcher = cv2.DescriptorMatcher_create(cv2.DESCRIPTOR_MATCHER_BRUTEFORCE_HAMMING)
#matcher = cv2.FlannBasedMatcher()
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
# Find nearest neighbor approximate matching
flann = cv2.FlannBasedMatcher(index_params, search_params)
# Use KNN to match descriptor
matches = flann.knnMatch(dp1, dp2, k=2)
# Calculate effective point
matchesMask = [[0, 0] for i in range(len(matches))]
# coff to design effective kp nums
coff = 0.3
good = []
for i, (m, n) in enumerate(matches):
if m.distance < coff * n.distance:
matchesMask[i] = [1, 0]
good.append(m)
draw_params = dict(matchColor=(0, 255, 0),
singlePointColor=(0, 0, 255),
matchesMask=matchesMask,
flags=0)
# Draw line
result1 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None, **draw_params)
result2 = cv2.drawMatchesKnn(img1_gray, kp1, img2_gray, kp2, matches, None, **draw_params)
# Find homography
if len(good) > 3:
src_pts = np.float32([ kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
h, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
# Use homography
height, width, channels = img2.shape
result = cv2.warpPerspective(img1, h, (width, height))
cv2.imshow("result", result)
cv2.imshow("result1", result1)
cv2.imshow("result2", result2)
cv2.waitKey(0)
效果图:
灰度图特征点匹配
彩色图特征点匹配
结果图