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

故事扮演 提交于 2019-12-17 21:11:35

问题


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.


回答1:


Here's a variant that has a few extra features relative to the other answers:

  • It allows you to omit the shape argument (default is 'full').
  • It only calls normxcorr2 when shape is a valid string.
  • It performs the indexing in one line using logical indexing. The sizes of the lead padding and desired center region is used to create index vectors of true and false values. The trailing padding doesn't need to be specified since a logical index that is shorter than the dimension it indexes will simply be padded with false values.

And here's the code:

function I = normxcorr2e(template, im, shape)

  if (nargin == 2) || strcmp(shape,'full')
      I = normxcorr2(template, im);
      return
  end

  switch shape
      case 'same'
          pad = floor(size(template)./2);
          center = size(im);
      case 'valid'
          pad = size(template) - 1;
          center = size(im) - pad;
      otherwise
          throw(Mexception('normxcorr2e:BadInput',...
              'SHAPE must be ''full'', ''same'', or ''valid''.'));
  end

  I = normxcorr2(template, im);
  I = I([false(1,pad(1)) true(1,center(1))], ...
        [false(1,pad(2)) true(1,center(2))]);

end



回答2:


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);



回答3:


There is not much elegance here - you run the correlation, then you remove what you can't use. But it works.

function I = normxcorr2e(template,im,shape)

%# perform cross correlation with automated zero-padding
I = normxcorr2(template,im);

switch shape
    case 'same'

        %# if we were guaranteed to have odd-sized templates only
        %# we would only need padLow
        templateSize = size(template);
        padLow = floor(templateSize/2);
        padHigh = templateSize - padLow - 1;

        I = I( (1+padLow(1)):(end-padHigh(1)), (1+padLow(2)):(end-padHigh(2)) );

    case 'full'
        %Do nothing
    case 'valid'
        %# with even size, we need to remove the larger of the two pad sizes
        %# i.e. padLow, on all sides
        templateSize = size(template);
        padLow = templateSize/2;

        I = I( (2*padLow(1)):(end-2*padLow(1)+1), (2*padLow(2)):(end-2*padLow(2)+1) );
    otherwise
        throw(Mexception('normxcorr2e:BadInput','shape %s is not recognized',shape));
end


来源:https://stackoverflow.com/questions/9145107/an-elegant-way-to-get-the-output-of-normxcorr2-in-a-manner-similar-to-conv2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!