机器视觉之尺度不变特征变换(SFIT)算法的实例教程

时间:2024-01-26 15:20:29

话不多说,上代码
原理和应用场景在文章最后

import cv2
import numpy as np

# 读取图片
img1 = cv2.imread('你自己的第一张照片的路径', 0) #像我这样: img1 = cv2.imread('/home/local/wang/Downloads/MicrosoftTeams-image (12).png', 0)

img2 = cv2.imread('你自己的第二张照片的路径', 0)

# 初始化SIFT检测器
sift = cv2.SIFT_create()

# 寻找关键点和描述符
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# 创建BFMatcher对象
bf = cv2.BFMatcher()

# 使用KNN匹配
matches = bf.knnMatch(des1, des2, k=2)

# 应用比率测试
good_matches = []
for m, n in matches:
    if m.distance < 0.75 * n.distance:
        good_matches.append(m)

# 绘制匹配结果
img_matches = cv2.drawMatches(img1, kp1, img2, kp2, good_matches, None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)

# 显示结果
cv2.imshow('Matches', img_matches)
cv2.waitKey(0)
cv2.destroyAllWindows()

使用SIFT进行图片的简单操作:

import cv2
import numpy as np

def rotate_images(image1, image2):
    # 转换为灰度图
    gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)

    # 使用SIFT检测关键点和计算描述符
    sift = cv2.SIFT_create()
    kp1, des1 = sift.detectAndCompute(gray1, None)
    kp2, des2 = sift.detectAndCompute(gray2, None)

    # 使用FLANN匹配器
    index_params = dict(algorithm=0, trees=5)
    search_params = dict(checks=50)
    flann = cv2.FlannBasedMatcher(index_params, search_params)
    matches = flann.knnMatch(des1, des2, k=2)

    # 筛选好的匹配
    good_matches = []
    for m, n in matches:
        if m.distance < 0.75 * n.distance:
            good_matches.append(m)

    # 获取匹配点的坐标
    src_pts = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
    dst_pts = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)

    # 通过求解基础矩阵进行图像配准
    M, _ = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC)

    # 通过基础矩阵计算旋转角度
    rotation_angle = np.arctan2(M[1, 0], M[0, 0]) * (180 / np.pi)

    # 旋转图像
    rotated_image = cv2.warpPerspective(image1, M, (image1.shape[1], image1.shape[0]))

    # 绘制匹配结果
    img_matches = cv2.drawMatches(image1, kp1, image2, kp2, good_matches, None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)

    return rotated_image, img_matches, rotation_angle

# 读取两个图像
image1 = cv2.imread('你自己的第一张照片的路径')
image2 = cv2.imread('你自己的第二张照片的路径')

# 进行图像配准和旋转估计
rotated_image, img_matches, rotation_angle = rotate_images(image1, image2)

# 显示结果
cv2.imshow('Original Image 1', image1)
cv2.imshow('Original Image 2', image2)
cv2.imshow('Rotated Image', rotated_image)
cv2.imshow('Matches', img_matches)
# cv2.waitKey(0)
# cv2.destroyAllWindows()

print('Estimated Rotation Angle:', rotation_angle)
 

SIFT(Scale-Invariant Feature Transform)是一种用于图像处理和计算机视觉的特征提取算法,它在处理具有不同尺度、旋转和光照变化的图像时表现出色。SIFT算法的主要应用方向和原理如下:
应用方向:

图像配准和匹配:
SIFT可以用于在不同图像中找到相同的关键点,从而进行图像配准和匹配。这在计算机视觉领域中的物体识别和场景重建中非常有用。

目标跟踪:
SIFT特征可以用于跟踪视频序列中的目标,即使目标发生旋转、缩放或部分遮挡。

图像拼接:
在全景图像拼接中,SIFT特征可以被用来找到不同图像中的匹配点,从而实现图像的平滑拼接。

三维重建:
SIFT特征对于不同视点的图像可以进行匹配,这对于三维重建和摄影测量学等应用非常重要。

图像检索:
SIFT特征可以用于图像检索,通过比较图像的关键点和描述子来找到相似的图像。

原理:

尺度不变性:
SIFT通过使用高斯差分金字塔来检测不同尺度下的关键点。这使得算法对于图像中的不同物体尺寸具有不变性。

旋转不变性:
SIFT通过在每个关键点周围的图像区域计算主方向,实现对于图像中的旋转具有不变性。

关键点检测:
SIFT使用高斯差分金字塔来检测图像中的局部极值点,这些点通常对应于图像的显著特征。

关键点描述:
对于每个关键点,SIFT计算描述子,该描述子是一个128维的向量,用于描述关键点周围区域的特征。

匹配:
在不同图像中,SIFT通过比较关键点的描述子来进行匹配。匹配的关键点对可以用于图像配准和其他应用。