Элегантный способ получить результат `normxcorr2` аналогично 'conv2' (удаление ненужных ребер).

Есть ли элегантный способ в Matlab получить вывод normxcorr2, обрезанный до размера изображения или обрезанный только до той части матрицы, которая не использует края с нулевым дополнением в вычислениях?

Чтобы понять, что я имею в виду, рассмотрим команду conv2. Существует необязательный параметр shape, для которого можно установить значение same или valid.

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

Например:

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

ответ =

45    45

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

ответ =

50    50

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

ответ =

55    55

В настоящее время я написал свою собственную функцию, которая делает что-то вроде этого:

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

У вас есть идея получше? Главным критерием успешного ответа будет элегантность предлагаемого решения.

Изменить(1) Прежде всего, спасибо за все ваши ответы. Все они хороши и одобрены мной. Я еще не решил, что лучше. Кстати, я недавно думал о случае, когда шаблон велик по сравнению с изображением. В этом случае имеет смысл ускорить вычисления, обрезав аргумент image перед запуском normxcorr2.


person Andrey Rubshtein    schedule 04.02.2012    source источник
comment
Правильность тоже считается? :)   -  person Jonas    schedule 05.02.2012
comment
@Jonas, да :) Элегантность - главный критерий, а не единственный   -  person Andrey Rubshtein    schedule 05.02.2012
comment
Я попытался найти способ, с помощью которого вы могли бы вызывать свою функцию по тому же имени и скрывать версию набора инструментов, позволяя ей действовать как невидимая оболочка. К сожалению, вызов теневой функции с помощью ВСТРОЕННЫЙ работает только для встроенные функции, не относящиеся к набору инструментов, поэтому я не мог заставить это работать.   -  person gnovice    schedule 08.02.2012
comment
@gnovice, это хорошая идея, но на практике это может вызвать хаос в развернутом коде :( Однажды я пытался переопределить disp, и поведение было очень странным.   -  person Andrey Rubshtein    schedule 08.02.2012


Ответы (3)


Вот вариант, который имеет несколько дополнительных функций по сравнению с другими ответами:

И вот код:

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
person gnovice    schedule 05.02.2012

Это было бы намного лаконичнее. Надеюсь, это то, что вы ищете:

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);
person Oli    schedule 05.02.2012
comment
Спасибо, ваша версия и все остальные хороши. Таким образом, они были проголосованы мной. Здесь у меня был сложный выбор. - person Andrey Rubshtein; 08.02.2012

Здесь нет особой элегантности — вы запускаете корреляцию, затем удаляете то, что не можете использовать. Но это работает.

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
person Jonas    schedule 05.02.2012
comment
Спасибо, ваша версия и все остальные хороши. Таким образом, они были проголосованы мной. Здесь у меня был сложный выбор. - person Andrey Rubshtein; 08.02.2012