An elegant way to get the output of `normxcorr2` in a manner similar to 'conv2' - (removing the unwanted edges)

Andrey Rubshtein picture Andrey Rubshtein · Feb 4, 2012 · Viewed 7.3k times · Source

Is there an elegant way in Matlab to get the output of normxcorr2 cropped to the size of the image or cropped only to the part of the matrix that does not use zero padded edges in computation?

To understand what I mean, consider the conv2 command. There is an optional parameter called shape that can be set to same or valid.

C = conv2(A,B,'same');
C = conv2(A,B,'valid');

For example:

size( conv2( rand(50,50) , rand(6,6), 'valid') ) 

ans =

45    45

size( conv2( rand(50,50) , rand(6,6), 'same') )

ans =

50    50

size( conv2( rand(50,50) , rand(6,6)) )

ans =

55    55

Currently I wrote my own function, that does something like this:

function I = normxcorr2e(template,im,shape)
    switch shape
        case 'same'
            I = normxcorr2(template,im);
            r = size(I,1)-size(im,1);
            c = size(I,2)-size(im,2);

            m1=floor(r/2);
            n1=floor(c/2);
            m2=ceil(r/2);
            n2=ceil(c/2);

            I(1:m2,:) = [];
            I(end-m1+1:end,:) = [];

            I(:,1:n2) = [];
            I(:,end-n1+1:end) = [];
        case 'full'
            %Do nothing
        case 'valid'
            %TODO - write this case...
        otherwise
            throw(Mexception('normxcorr2e:BadInput','shape %s is not recognized',shape));
    end

end

Do you have a better idea? The main criterion for a successful answer will be the elegance of the proposed solution.

Edit(1) First of all, thanks for all of your answers. All of them are good and upvoted by me. I still haven't decided which is the best. By the way, I am thinking recently about the case where the template is large compared to the image. In that case, it makes sense to speedup the computation by cropping the image argument before running normxcorr2.

Answer

Oli picture Oli · Feb 5, 2012

This would be much more concise. I hope it's what you're looking for:

function I = normxcorr2e(template,im,shape)

  args={'full','same','valid'};
  cropSize=(find(strcmp(shape,args))-1)*size(template);
  crop=@(x,r) x(1+floor(r(1)/2):end-ceil(r(1)/2),1+floor(r(2)/2):end-ceil(r(2)/2))
  I=crop(normxcorr2(template,im),cropSize);