Vlad 寻找相似图像,算法matlab实现

vlad算法的matlab实现

vlad算法介绍

vlad( Vector of Linearly Agregated Descriptors)主要用于相似图像的检索,主要的过程如下:
Vlad 寻找相似图像,算法matlab实现_第1张图片

  • 具体的理论内容建议参考:
  • blog1
  • blog2
  • 作者原文

具体的实现代码(matlab)

  • 这只是我的理解!!!!!
%% Display SIFT features of two images
%
clear;
close all;
clc;

%% An example to show how to find all files in a folder
srcFolderPath = './test images';
allFiles = dir(srcFolderPath);
imgCount = 0;
for i = 3 : length(allFiles) %从3开始
    fileName = allFiles(i).name;
    if length(fileName) > 3 && strcmp(fileName(end-3 : end), '.jpg') == 1 % find JPG image file
        imgCount = imgCount + 1;
        imgPath = [srcFolderPath, '/', fileName];
        fprintf('File %d: %s\n', imgCount, imgPath);
        sift = readsift(imgPath); % read sift--> 读取存储的sift算子
        SiftFeat{imgCount} = sift;%传入归一化后的sift,  而且已经被转制
    end
end

%% 第一步  将所有串起来  计算kmeans 聚类
sift_all = [];
for i=1:20
    sift_all = [sift_all;SiftFeat{i}];
end
[Idx_all,C] = kmeans(sift_all,32);

% 提取每幅图的Idx,方便计算累积残差

size_sift=zeros(1,20);
for i=1:20
     m = size(SiftFeat{i});% m代表了每一个图像的sift数目
     size_sift(i) = m(1);
end
sum_size = 1;
for i=1:20 
    temp_Idx = Idx_all(sum_size:sum_size+size_sift(i)-1);
    sum_size = sum_size+size_sift(i);
    Idx{i} = temp_Idx;
end

%% 第二步:计算每幅图和聚点的累计残差
for i=1:20  %一共20幅图像
    temp_v = zeros(32,128);%库存每一个vlad
    temp_sift = SiftFeat{i};
    for num_1=1:size_sift(i) %对这副图像计算累积残差
        temp_v(Idx{i}(num_1),:)=temp_v(Idx{i}(num_1),:)+temp_sift(num_1,:)-C(Idx{i}(num_1),:);
    end
    v_chuan = [];%串成一行
    for num_2=1:32
        v_chuan = [v_chuan,temp_v(num_2,:)];
    end
    v_chuan = bsxfun(@times, v_chuan, 1./sqrt(sum(v_chuan.^2,2))) ;%归一化操作
    v{i}= v_chuan;
end

%% 第三步  计算每幅图累计残差的 欧氏距离
result_Ech = zeros(20,20);
for i=1:20
    for j=1:20
        result_Ech(i,j) = sum((v{i}-v{j}).^2);
    end
end

%% 提取距离最小的前四幅图的id
temp_result = sort(result_Ech,2);%距离排序
result = zeros(20,4);%最终前四距离索引
for i=1:20
    for j=1:4
        temp_find = find(result_Ech(i,:)==temp_result(i,j));
        result(i,j) = temp_find(1);%防止距离相同
    end
end

%% 计算前四幅图  相关程度  范围在 1-4 之间
for i=1:5 %一共五组数据
    class{i} = [(i-1)*4+1:(i-1)*4+5];
end

for i=1:20
    num_result = 1;
    for j=2:4
        temp = find(class{ceil(i/4)}==result(i,j));
        if ~isempty(temp)
            num_result = num_result+1;
        end
        result_one(i) = num_result;
    end
end

result_average = mean(result_one)
  • 其中readsift 是读取图片之前计算的sift算子, 一共二十副图像,分五类(每类四幅)。
function SiftFeat = readsift(imgPath)
%%第一步  读取Sift 局部特征
src_1 = imgPath;
ext1 = '.dsift'; %'.vsift_640'; % extension name of SIFT file
siftDim = 128;
% im_1 = imread(src_1);
% figure,imshow(im_1);

featPath_1 = [src_1, ext1];
fid_1 = fopen(featPath_1, 'rb');
featNum_1 = fread(fid_1, 1, 'int32'); % 文件中SIFT特征的数目
SiftFeat_1 = zeros(siftDim, featNum_1);
% paraFeat_1 = zeros(4, featNum_1);
for i = 1 : featNum_1 % 逐个读取SIFT特征
    SiftFeat_1(:, i) = fread(fid_1, siftDim, 'uchar'); %先读入128维描述子
    %     paraFeat_1(:, i) = fread(fid_1, 4, 'float32');     %再读入[x, y, scale, orientation]信息
end
fclose(fid_1);

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

%% 返回结果
SiftFeat = SiftFeat_1';

end

本文用到的图片资源

  • 以上code都是我自己的理解,如果有错误或者不妥的地方,欢迎补充改进!非常感谢!

你可能感兴趣的:(图像作业)