2011-03-24 19 views
5

Estoy creando un algoritmo que extrae información de las imágenes; la mayoría de estas informaciones son datos energéticos. Esto se hace básicamente al recorrer la imagen con un núcleo (el tamaño se da como parámetro) y obtener las sumas cuadradas de valores en ese kernel.¿Cómo eliminar el bucle en el cálculo de la energía?

Esto se realiza en tres escalas, donde los tres tamaños de kernel (parche) son (en este punto): smallestPatchSize, smallestPatchSize * 3, smallestPatchSize * 9 (con núcleos superpuestos en el segundo y tercer caso). Esto se hace para varios canales de color, filtros de gradiente, etc. (17 de estos en total).

Mi pregunta es si es posible vectorizar el código a continuación; obviamente, esta parte del código requiere mucho más tiempo para ejecutarse que cualquier otra. Estoy bastante un principiante en Matlab y todavía trato de conseguir la caída de vectorización pero este me :)

for dim = 1:17 

for i = 1:smallestPatchSize:(size(image,1) - currentPatchSize) 
    for j = 1:smallestPatchSize:(size(image,2) - currentPatchSize) 

     % calculate the position in the energy matrix 
     % which has different dimensions than the input pictures 
     iPosition = (i - 1 + smallestPatchSize)/smallestPatchSize; 
     jPosition = (j - 1 + smallestPatchSize)/smallestPatchSize; 

     % calculate the energy values and save them into the energy matrix 
     energy(iPosition, jPosition, dim) = sum(sum(abs(... 
      filters(i:i+currentPatchSize, j:j+currentPatchSize,dim))))^2; 
    end 
end 
end 

Gracias de antemano Beats - esta es mi primera pregunta StackOverflow :) @

Respuesta

3

Está tomando sumas de valores locales de bloques. Un filtro de suma es separable, es decir, si desea hacer una suma sobre m-by-n, puede dividirla en tomar primero la suma m-por-1, y luego la suma 1-por-n en el resultado . Tenga en cuenta que con una convolución completa tomará la suma un poco más a menudo, pero es aún más rápido que con blkproc o el más reciente blockproc.

Por lo tanto, incluso para smallestPatchSize, se puede escribir el bucle interno como:

tmp = conv2(... 
      conv2(abs(filter),ones(currentPatchSize,1),'same'),... 
     ones(1,currentPatchSize,'same').^2; 
%# tmp contains the energy for a sliding window filter. 
energy = tmp((currentPatchSize/2+1):(currentPatchSize+1):size(image,1)-(currentPatchSize/2+1),... 
     (currentPatchSize/2+1):(currentPatchSize+1):size(image,2)-(currentPatchSize/2+1)); 
+0

Lo siento por no conseguir de nuevo a usted antes, tenía un par de bonitos semanas ocupadas Gracias - finalmente he utilizado una solución como esta con pequeños cambios y redujo significativamente el tiempo (radicalmente para pequeños núcleos) :) – Oszkar

1

Si tener acceso al paquete de herramientas de procesamiento de imágenes puede utilizar blkproc:

B = blkproc(A,[m n],fun) 

En su caso:

[m,n] = size(filters) ./ patchSize; 
fun = @(x) sum(sum(x^2)); % or whatever 

B debe terminar siendo el tamaño correcto. También puede usar regiones superpuestas si lo desea.

Cuestiones relacionadas