在MATLAB中减少RANSAC代码中的维度

时间:2014-08-24 19:05:56

标签: matlab

我正在尝试减少RANSAC代码中的维度。这是原始代码:

function [ output_args ] = ransac( filename)

mov = VideoReader(filename);
numFrames = mov.NumberOfFrames;

for i=1:numFrames
    file_name = sprintf('frames/%0.3i.jpg', i);
    file_name2 = sprintf('frames/%0.3i.jpg', i+1);

    I1=im2double(imread(file_name2));
    I2=im2double(imread(file_name));

    % Get the Key Points
    Options.upright=true;
    Options.thresh=0.0001;
    Ipts1=OpenSurf(I1,Options);
    Ipts2=OpenSurf(I2,Options);

    % Put the landmark descriptors in a matrix
    D1 = reshape([Ipts1.descriptor],64,[]);
    D2 = reshape([Ipts2.descriptor],64,[]);

    % Find the best matches
    err=zeros(1,length(Ipts1));
    cor1=1:length(Ipts1);
    cor2=zeros(1,length(Ipts1));

    for i=1:length(Ipts1),
        distance=sum((D2-repmat(D1(:,i),[1 length(Ipts2)])).^2,1);
        [err(i),cor2(i)]=min(distance);
    end

    % Sort matches on vector distance
    [err, ind]=sort(err);
    cor1=cor1(ind);
    cor2=cor2(ind);

    % Make vectors with the coordinates of the best matches
    Pos1=[[Ipts1(cor1).y]',[Ipts1(cor1).x]'];
    Pos2=[[Ipts2(cor2).y]',[Ipts2(cor2).x]'];
    Pos1=Pos1(1:30,:);
    Pos2=Pos2(1:30,:);

    % Show both images
    I = zeros([size(I1,1) size(I1,2)*2 size(I1,3)]);
    I(:,1:size(I1,2),:)=I1; I(:,size(I1,2)+1:size(I1,2)+size(I2,2),:)=I2;

    % Calculate affine matrix
    Pos1(:,3)=1; Pos2(:,3)=1;
    M=Pos1'/Pos2';

    % Add subfunctions to Matlab Search path
    functionname='OpenSurf.m';
    functiondir=which(functionname);
    functiondir=functiondir(1:end-length(functionname));
    addpath([functiondir '/WarpFunctions'])

    % Warp the image
    I1_warped=affine_warp(I1,M,'bicubic');

    % Show the result
    subplot(1,3,1), imshow(I1);title('Figure 1');
    subplot(1,3,2), imshow(I2);title('Figure 2');
    subplot(1,3,3), imshow(I1_warped);title('Warped Figure 1');

    imwrite(I1_warped,file_name2);
    if (mod(i,20) == 0)  
       disp(sprintf('he make a %d',i)); 
    end
end
sprintf('finish'); 

当我更改行中的值

D1 = reshape([Ipts1.descriptor],64,[]);
D2 = reshape([Ipts2.descriptor],64,[]);

为:

D1 = reshape([Ipts1.descriptor],32,[]);
D2 = reshape([Ipts2.descriptor],32,[]);

我收到以下错误:

  

使用时出错 -
  矩阵尺寸必须一致。   ransac (line 33)

出错      

distance=sum((D2-repmat(D1(:,i),[1 length(Ipts2)])).^2,1);

为什么我收到此错误?

1 个答案:

答案 0 :(得分:0)

由于您更改了D1D2的尺寸,此行不再有效:

distance=sum((D2-repmat(D1(:,i),[1 length(Ipts2)])).^2,1);

D1D2中发生的事情是,它正在采用一维向量并将其重新整形为一个包含64行的矩阵。我假设SURF描述符的每个关键点都表示为64个元素向量。您现在可能正在使用32,因为您希望将每个SURF描述符表示为32个而不是64个。如果这样做,您将使用两个列来表示原始代码具有此功能的单个功能每个功能一列。因此,在进行距离计算时,它不会像使用64行重新整形时那样复制总列数,列的总数正好是检测到的关键点总数来自SURF。

我建议你做的是配置SURF描述符,使每个功能的输出为32个,而不是64个。但是,如果你想让这个语句起作用,你需要更改{{1} }}语句用于计算lengthD1中的列数。就这样:

D2

我不相信上述陈述会正确地确定要素之间的距离,因为每列基本上都是要素的一半,所以如果要找到最佳匹配要素,它会选择最佳列...而且,这只是一个功能的一半。

我建议您再次阅读SURF,因为只需将重塑从64更改为32,会降低功能的维度。


旁注

如果您想完全避免此矩阵维度错误,我会亲自使用bsxfun,因为它会自动为您复制维度,而不会distance=sum((D2-repmat(D1(:,i),[1 size(D2,2)])).^2,1); 。因此,我个人会用以下代码替换该行代码:

repmat