xcorr images example espaƱol cross matlab convolution cross-correlation

matlab - images - Una forma elegante de obtener la salida de `normxcorr2` de manera similar a ''conv2''-(eliminando los bordes no deseados)



cross correlation python (3)

No hay mucha elegancia aquí: ejecuta la correlación, luego elimina lo que no puede usar. Pero funciona.

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

¿Existe una forma elegante en Matlab de obtener la producción de normxcorr2 recortada al tamaño de la imagen o recortada solo en la parte de la matriz que no utiliza bordes acolchados cero en el cálculo?

Para entender lo que quiero decir, considere el comando conv2 . Hay un parámetro opcional llamado shape que puede establecerse en el same o valid .

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

Por ejemplo:

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

Actualmente escribí mi propia función, que hace algo como esto:

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

Tienes una mejor idea? El criterio principal para una respuesta exitosa será la elegancia de la solución propuesta.

Editar (1) Antes que nada, gracias por todas sus respuestas. Todos ellos son buenos y han sido votados por mí. Todavía no he decidido cuál es el mejor. Por cierto, estoy pensando recientemente en el caso en que la plantilla es grande en comparación con la imagen. En ese caso, tiene sentido acelerar el cálculo recortando el argumento de la image antes de ejecutar normxcorr2 .


Aquí hay una variante que tiene algunas características adicionales en relación con las otras respuestas:

  • Le permite omitir el argumento de forma (el valor predeterminado es ''full'' ).
  • Solo llama a normxcorr2 cuando la shape es una cadena válida.
  • Realiza la indexación en una línea usando indexación lógica . Los tamaños del relleno de relleno y la región central deseada se utilizan para crear vectores de índice de valores verdaderos y falsos. No es necesario especificar el relleno final, ya que un índice lógico que es más corto que la dimensión que indexa simplemente se rellenará con valores falsos.

Y aquí está el código:

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


Esto sería mucho más conciso. Espero que sea lo que estás buscando:

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