DIA實驗——匹配幾何校驗

匹配幾何校驗

一、 任務描述

  1. 給定一對圖像,利用提取好的SIFT特徵文件,根據距離閾值準則(跨圖像的局部SIFT特徵距離小於0.4),得到圖像間的初始局部特徵匹配關係;
  2. 基於上述初步匹配結果,實現spatial coding方法,進行匹配校驗,確定幾何不一致的匹配;
  3. 將幾何一致的匹配和不一致的匹配在圖像上畫出來,分別用藍色和紅色進行區分。

二、 實驗步驟

  1. 尋找匹配對:尋找並提取第1張圖與第2張圖的SIFT描述子匹配對的(x,y)座標點集,分別放進維數爲(2*對應點數)的矩陣Map1,Map2中。
  2. 生成空間映射:根據Map1,Map2每個點相對其他點座標的左右上下位置關係,以及k種(本實驗中取k=4)旋轉角度,生成由0、1構成的維數爲(對應點數對應點數k)的空間編碼矩陣GX1,GY1,GX2,GY2中。
  3. 計算不一致性矩陣:將空間編碼矩陣GX1與GX2,GY1與GY2進行邏輯異或操作得到不一致性矩陣Vx,Vy。
  4. 計算不一致性總和Sx,Sy: 矩陣Vx,Vy各行元素求和,再對k個方向各行元素和求總和,得到Sx,Sy,維數爲(匹配點數*1)
  5. 檢查Sx,Sy,識別錯誤匹配項:首先基於Vx,計算Sx,找到對應的i*, 然後從Vx和Vy中把對應的第i行、第i列全部刪掉(或者mask掉,本實驗中以置零方式進行mask),隨後立即更新紅藍連線;然後基於更新後的Vy,計算Sy,找到對應的j*, 然後從Vx和Vy中把對應的第j行、第j列全部刪掉(或者mask掉,本實驗中以置零方式進行mask),隨後立即更新紅藍連線。 對更新後的Vx和Vy重複上面兩步,直到收斂(本實驗取不一致性總和的閾值爲(0.8*匹配對數)取整)。

三、 實驗效果

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

四、 實驗代碼

其中本實驗對圖像特徵描述子的讀取通過已準備好的“.sift”文件直接讀進matlab中,也可以自己在matlab中讀取“.jpg”圖片後轉爲SIFT格式的描述子數據,matlab代碼如下:

%% Set path and parameters
clear;
close all;
clc;

src_1 = './test images/37967br1.jpg';  
src_2 = './test images/791.jpg';

% src_1 = './test images/4.jpg';  
% src_2 = './test images/Apollo-266.jpg';

% src_1 = './test images/771.jpg';  
% src_2 = './test images/305.jpg';

% src_1 = './test images/Apollo-49.jpg';
% src_2 = './test images/Apollo-266.jpg';

ext = '.sift'; % extension name of SIFT file
siftDim = 128;
maxAxis = 400;


%%  Load image
im_1 = imread(src_1);
if max(size(im_1)) > maxAxis
    im_1 = imresize(im_1, maxAxis / max(size(im_1)));
end

im_2 = imread(src_2);
if max(size(im_2)) > maxAxis
    im_2 = imresize(im_2, maxAxis / max(size(im_2)));
end


%%  Load SIFT feature from file
featPath_1 = [src_1, ext];
featPath_2 = [src_2, ext];

fid_1 = fopen(featPath_1, 'rb');
featNum_1 = fread(fid_1, 1, 'int32');
SiftFeat_1 = zeros(siftDim, featNum_1);
paraFeat_1 = zeros(4, featNum_1);
for i = 1 : featNum_1
    SiftFeat_1(:, i) = fread(fid_1, siftDim, 'uchar');
    paraFeat_1(:, i) = fread(fid_1, 4, 'float32');
end
fclose(fid_1);

fid_2 = fopen(featPath_2, 'rb');
featNum_2 = fread(fid_2, 1, 'int32');
SiftFeat_2 = zeros(siftDim, featNum_2);
paraFeat_2 = zeros(4, featNum_2);
for i = 1 : featNum_2
    SiftFeat_2(:, i) = fread(fid_2, siftDim, 'uchar');
    paraFeat_2(:, i) = fread(fid_2, 4, 'float32');
end
fclose(fid_1);


%%Normalization
SiftFeat_1 = SiftFeat_1 ./ repmat(sqrt(sum(SiftFeat_1.^2)), size(SiftFeat_1, 1), 1);
SiftFeat_2 = SiftFeat_2 ./ repmat(sqrt(sum(SiftFeat_2.^2)), size(SiftFeat_2, 1), 1);


%% Check match based on distances between SIFT descriptors across images
normVal = mean(sqrt(sum(SiftFeat_1.^2)));
matchInd = zeros(featNum_1, 1);
matchDis = zeros(featNum_1, 1);
validDis = [];
gridDisVec = [];
ic = 0;
for i = 1 : featNum_1                                           %以第一張圖描述子數量爲基準進行匹配
    tmpFeat = repmat(SiftFeat_1(:, i), 1, featNum_2);   % repmat(A,m,n),將矩陣 A 複製 m×n 塊,即128*featNum_2
    d = sqrt(sum((tmpFeat - SiftFeat_2).^2)) / normVal; % L2 distance,圖1第i個描述子與圖2所有描述子的距離向量
    matchDis(i) = min(d);
    [v, ind] = sort(d);
    if v(1) < 0.4            % 最小距離小於0.4,則認爲構成一對匹配
        matchInd(i) = ind(1);
        ic = ic + 1;
        validDis(ic, 1 : 3) = [v(1), v(2), v(1) / v(2)];
        tmp = (SiftFeat_1(:, i) - SiftFeat_2(:, ind(1))).^2;
        tmp2 = reshape(tmp(:), 8, 16);
        gridDisVec(ic, 1 : 16) = sqrt(sum(tmp2));       % 第ic個匹配描述子的L2距離
    end
end
figure; stem(matchDis); ylim([0, 1.2]);                    %繪製莖狀圖
figure; stem(matchDis(matchInd > 0)); ylim([0, 1.2]);

%% 實現spatial coding方法,進行匹配校驗準備
Map1 = [];
Map2 = [];
m= 1;
for i = 1 : featNum_1
    if matchInd(i) > 0
        Map1 = [Map1, paraFeat_1(1:2, i)];
        Map2 = [Map2, paraFeat_2(1:2, matchInd(i))];
    end
end
%         xys = paraFeat_1(:, i);
%         xys2 = paraFeat_2(:, matchInd(i));
r = 4;    
GX1(ic, ic, r) = 0;
GY1(ic, ic, r) = 0;
GX2(ic, ic, r) = 0;
GY2(ic, ic, r) = 0;
for k = 1:r
    %將其分解爲r個獨立的子區域,旋轉k個單位的座標集
    theta = (k-1)*pi/(2*r);
    G1(1:2, 1:ic, k) = [cos(theta), -sin(theta); sin(theta), cos(theta)]*Map1;
    G2(1:2, 1:ic, k) = [cos(theta), -sin(theta); sin(theta), cos(theta)]*Map2;
    %獲取空間編碼01矩陣
    for i = 1:ic
        for j = 1:ic
            if G1(1, i, k) >= G1(1, j, k) 
                GX1(j, i, k) = 1;
            end
            if G1(2, i, k) >= G1(2, j, k) 
                GY1(i, j, k) = 1;
            end
            if G2(1, i, k) >= G2(1, j, k) 
                GX2(j, i, k) = 1;
            end
            if G2(2, i, k) >= G2(2, j, k) 
                GY2(i, j, k) = 1;
            end
        end
    end
end
Vx = xor(GX1, GX2);
Vy = xor(GY1, GY2);

%% Show the local matching results on RGB image
[row, col, cn] = size(im_1);
[r2, c2, n2] = size(im_2);
imgBig = 255 * ones(max(row, r2), col + c2, 3);
imgBig(1 : row, 1 : col, :) = im_1;
imgBig(1 : r2, col + 1 : end, :) = im_2;
% np = 40;
% thr = linspace(0,2*pi,np) ;
% Xp = cos(thr);
% Yp = sin(thr);
paraFeat_2(1, :) = paraFeat_2(1, :) + col;      %爲了讓兩幅圖畫面並排,使右側圖x座標右移col個單位
figure(3); imshow(uint8(imgBig)); axis on;
hold on;
matchCount = 0;
for i = 1 : featNum_1
    if matchInd(i) > 0
        matchCount = matchCount + 1;
        xys = paraFeat_1(:, i);
        xys2 = paraFeat_2(:, matchInd(i));
        figure(3);
%         hold on;
%         plot(xys(1) + Xp * xys(3) * 6, xys(2) + Yp * xys(3) * 6, 'r');                      %1匹配描述子紅圈
%         plot(xys2(1) + Xp * xys2(3) * 6, xys2(2) + Yp * xys2(3) * 6, 'r');              %2匹配描述子紅圈
        hold on; plot([xys(1), xys2(1)], [xys(2), xys2(2)], '-b', 'LineWidth', 0.8);    
    end
end

%% 幾何匹配校驗
Map2(1, :) = Map2(1, :) + col;      %爲了讓兩幅圖畫面並排,使右側圖x座標右移col個單位
threshold = floor(ic*0.8);
for i = 1:ic
    Sx = sum(sum(Vx, 2), 3);    %矩陣各行元素求和,再對k個方向各行元素和求總和
    [Cx, Ix] = max(Sx(:, :), [], 1); %求出第k個方向的列最大值
    if Cx>threshold
        Vx(Ix, :, :) = 0;       %把最不匹配的描述子mask
        Vx(:, Ix, :) = 0;
        Vy(Ix, :, :) = 0;       %把最不匹配的描述子mask
        Vy(:, Ix, :) = 0;
        hold on;plot([Map1(1, Ix), Map2(1, Ix)], [Map1(2, Ix), Map2(2, Ix)], '-r', 'LineWidth', 0.8);    %不匹配的描述點對連線
    end
    Sy = sum(sum(Vy, 2), 3);    %矩陣對各行元素求和
    [Cy, Iy] = max(Sy(:, :), [], 1);
    if Cy>threshold
        Vx(Iy, :, :) = 0;       %把最不匹配的描述子mask
        Vx(:, Iy, :) = 0;
        Vy(Iy, :, :) = 0;       %把最不匹配的描述子mask
        Vy(:, Iy, :) = 0;
        hold on;plot([Map1(1, Iy), Map2(1, Iy)], [Map1(2, Iy), Map2(2, Iy)], '-r', 'LineWidth', 0.8);    %不匹配的描述點對連線
    end
end
figure(3);
title(sprintf('Total local matches : %d (%d-%d)', length(find(matchInd)), featNum_1 ,featNum_2));
hold off;

五、參考文獻

代碼及資料
Wengang Zhou, Yijuan Lu, Houqiang Li, Y. Song, and Qi Tian, “Spatial coding for large scale partial-duplicate web image search,” ACM International Conference on Multimedia (MM), pp.131-140, 2010.
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章