Opencv(四)SIFT算法的实现

SIFT方法是基于图像尺度空间理论提出并发展起来的一种算法,相比梯度、哈希以及Harris特征检测算子而言,SIFT算子能够提供最为稳定的尺度、旋转以及平移不变特征。同时,对于光照及噪声的影响也具有较强的抵抗性。 具体的SIFT理论知识可以参考以下链接:
https://blog.csdn.net/zddblog/article/details/7521424

环境Anaconda3(Spyder)+Python3.8.8+OpenCV4.5.4.58

生成特征点的代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt

file = 'lena.jpg'
image = cv2.imread(file)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print(gray.shape)
sift = cv2.xfeatures2d.SIFT_create()
keypoints, descriptor = sift.detectAndCompute(gray, None)
print(len(keypoints))
print(keypoints[0].pt)
image = cv2.drawKeypoints(image=image, outImage=image, keypoints=keypoints, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS,
                        color=(0, 0, 255))
cv2.imwrite('sift.jpg', image)
plt.imshow(image)
plt.show()

原图:
Opencv(四)SIFT算法的实现_第1张图片

实现结果:
生成的图片会放在和代码文件同一路径下。此处的图片名称为:“sift.jpg”。
Opencv(四)SIFT算法的实现_第2张图片

对特征点进行检测之后,对原图进行适当的修改(旋转、改变亮度等),同时保证修改之后两图的长宽还是一样的值(如两图都为512*512)。

修改后的原图:
Opencv(四)SIFT算法的实现_第3张图片

新建一个.py文件,对两幅图的特征点进行连接,代码如下:

import numpy as np
import cv2
from matplotlib import pyplot as plt
from PIL import Image
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


imgname1 = 'lena.jpg'
imgname2 = 'lena_xiugai.jpg'
sift = cv2.xfeatures2d.SIFT_create()
img1 = cv2.imread(imgname1)
gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) #灰度处理图像
kp1, des1 = sift.detectAndCompute(img1,None)   #des是描述子

img2 = cv2.imread(imgname2)
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)#灰度处理图像
kp2, des2 = sift.detectAndCompute(img2,None)  #des是描述子

hmerge = np.hstack((gray1, gray2)) #水平拼接
if 0:
    cv2.imshow("gray", hmerge) #拼接显示为gray
    

img3 = cv2.drawKeypoints(img1,kp1,img1,)#flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
img4 = cv2.drawKeypoints(img2,kp2,img2)
hmerge = np.hstack((img3, img4)) #水平拼接
if 0:
    cv2.imshow("point", hmerge) #拼接显示为gray
    
# BFMatcher解决匹配
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2, k=2)

# 调整ratio
good = []
for m,n in matches:
    if m.distance < 0.8*n.distance:
        good.append([m])
# 输出
img5 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=2)
cv2.imwrite('1_2match.jpg', img5)

注意要先执行第一部分的代码之后再执行第二部分的代码。
结果如下:
Opencv(四)SIFT算法的实现_第4张图片
此文没有对错误点进行修正,具体实现可参考其他文章。

参考链接:
https://blog.csdn.net/zddblog/article/details/7521424
https://baike.baidu.com/item/SIFT%E5%8C%B9%E9%85%8D%E6%96%B9%E6%B3%95

你可能感兴趣的:(Opencv实践,opencv,windows,python)