基于SIFT算法的图像匹配

基本概念

尺度不变特征转换(Scale-invariant feature transform,简称SIFT) ,是一种用来侦测与描述影像中的局部性特征的算法,它在空间尺度中寻找极值点,提取位置、尺度、旋转不变量,生成特征描述子。 SIFT算法的实质是在不同的尺度空间上查找关键点(特征点),并计算出关键点的方向。

计算步骤

SIFT****算法主要分以下步骤:

(1)尺度空间极值点检测:搜索所有尺度上的图像位置,通过高斯微分函数来识别潜在的对于尺度和旋转不变的兴趣点。

(2)筛选出稳定的关键点:在每个候选的位置上,通过一个拟合精细的模型来确定位置和尺度。关键点的选择依据于它们的稳定程度。

(3)确定关键点方向:基于图像局部的梯度方向,分配给每个关键点位置一个或多个方向。所有后面的对图像数据的操作都相对于关键点的方向、尺度和位置进行变换,从而提供对于这些变换的不变性。

(4)生成特征点描述子:在每个关键点周围的邻域内,在选定的尺度上测量图像局部的梯度。这些梯度被变换成一种表示,这种表示允许比较大的局部形状的变形和光照变化。

(5)特征点匹配

Matlab代码

Matlab 复制代码
%该函数读取图像并返回其SIFT"关键点"
function [image, descriptors, locs] = sift(imageFile)
image = imread(imageFile);               % 读图
[rows, cols] = size(image); 
% 转换为PGM格式,便于"关键点"可执行文件的读取
f = fopen('tmp.pgm', 'w');
if f == -1
    error('Could not create file tmp.pgm.');
end
fprintf(f, 'P5\n%d\n%d\n255\n', cols, rows);
fwrite(f, image', 'uint8');
fclose(f);
%调用"关键点"可执行文件
if isunix
    command = '!./sift ';
else
    command = '!siftWin32 ';
end
command = [command ' <tmp.pgm >tmp.key'];
eval(command);
g = fopen('tmp.key', 'r');
if g == -1
    error('Could not open file tmp.key.');
end
[header, count] = fscanf(g, '%d %d', [1 2]);
if count ~= 2
    error('Invalid keypoint file beginning.');
end
num = header(1);
len = header(2);
if len ~= 128
    error('Keypoint descriptor length invalid (should be 128).');
end
% x1, y1; 起始点
% x2, y2; 终止点
function TransformLine(imsize, keypoint, x1, y1, x2, y2)
len = 6 * keypoint(3);
s = sin(keypoint(4));
c = cos(keypoint(4));
% 变换
r1 = keypoint(1) - len * (c * y1 + s * x1);
c1 = keypoint(2) + len * (- s * y1 + c * x1);
r2 = keypoint(1) - len * (c * y2 + s * x2);
c2 = keypoint(2) + len * (- s * y2 + c * x2);
line([c1 c2], [r1 r2], 'Color', 'c');
%% 该函数读取两张图像,并找到它们的SIFT特征
function num = match(image1, image2)
[im1, des1, loc1] = sift(image1);    %找出每张图的SIFT关键点
[im2, des2, loc2] = sift(image2);
distRatio = 0.6;   
des2t = des2';            %预计算矩阵转置
for i = 1 : size(des1,1)
   dotprods = des1(i,:) * des2t;        % 点积向量
   [vals,indx] = sort(acos(dotprods));  %取反余弦并对结果进行排序 
   %检查最近邻的角度是否小于2*distRatio.
   if (vals(1) < distRatio * vals(2))
      match(i) = indx(1);
   else
      match(i) = 0;
   end
end
% 显示匹配点连接的图像
newImg = cat(2,im1,im2);  %将两张图像放在一张图中
figure; imshow(newImg)
hold on
plot(loc1(:,2),loc1(:,1), 'ro','MarkerSize',5,'LineWidth',0.7)
plot(loc2(:,2)+size(im1,1),loc2(:,1), 'm*','MarkerSize',5,'LineWidth',0.7)
cols1 = size(im1,2);
for i = 1: size(des1,1)
  if (match(i) > 0)
    line([loc1(i,2) loc2(match(i),2)+cols1], ...
         [loc1(i,1) loc2(match(i),1)], 'Color', 'c');
  end
end
hold off;
num = sum(match > 0);
fprintf('Found %d matches.\n', num);
% 保存结果
frame=getframe(gcf);
im=frame2im(frame);
imwrite(im,'S图像匹配结果.jpg'); 
%% 主程序
img1=imread('baby1.JPG');
img2=imread('baby2.JPG');
img1_gray=rgb2gray(img1);
img2_gray=rgb2gray(img2);
match('img1_gray.jpg',' img2_gray.jpg ');

匹配结果

相关推荐
别动我齐刘海35 分钟前
机器人运动控制学习2——基础进阶
c++·人工智能·神经网络·学习·目标检测·机器学习·机器人
冬奇Lab1 小时前
Code Agent 解剖(05):模型怎么知道有哪些工具可以用?Function Calling 如何实现?
人工智能·开源·agent
ZGIAI1 小时前
ZGI Workflow:让知识检索进入业务流程
人工智能·架构
ZGIAI1 小时前
ZGI 模型网关:统一接入与路由大模型
人工智能·架构
冬奇Lab1 小时前
开源项目第193期:Semantica — 开源版 Palantir for AI Agent,知识图谱 + 确定性推理 + W3C 溯源,让 AI 决策可追溯、可审计、可合规
人工智能·开源·资讯
雷帝木木2 小时前
数据湖与数据仓库:从理论到实践
人工智能·python·深度学习·机器学习
小小测试开发2 小时前
AI Agent 评测确定性:snapshot → fork → act → assert → diff 的状态孪生测试世界
人工智能
咖啡星人k2 小时前
2025 AI编程进入“自动驾驶“时代:我用MonkeyCode把Agent、MCP和AI原生工作流跑通了
人工智能·自动驾驶·prompt·aigc·ai编程·ai-native
wenyq72 小时前
LeetCode 2460. Apply Operations to an Array
算法·leetcode
jike_20262 小时前
4款会议翻译转写工具对比:多语言、方言和线下会议怎么选?
人工智能·语音识别·iphone