2011-03-06 8 views
7

Tengo una sección de código que encuentra las esquinas de Harris en una secuencia de imágenes. Necesito hacer esto para 92 imágenes, pero es bastante lento. Como tal, me gustaría ejecutar el código en paralelo. El código que tengo a continuación tiene un error relacionado con las "esquinas" variablesMATLAB parfor slicing issue?

%% Harris corners 
    max_pts = 900; 
    corners = zeros(max_pts,2,size(images,3)); 
    parfor i = 1:size(images,3) 
     I = images(:,:,i); 
     [y x] = get_corners(I,max_pts); 
     corners(1:length(y),:,i) = [y x]; 
    end 

que dice:

MATLAB ejecuta bucles en funciones parfor dividiendo las iteraciones del bucle en grupos, y luego enviarlos a los trabajadores de MATLAB donde corren en paralelo. Para que MATLAB haga esto de manera repetible y confiable, debe ser capaz de clasificar todas las variables utilizadas en el ciclo. El código usa la variable indicada de una manera que es incompatible con la clasificación. Acción sugerida Soluciona el uso de la variable indicada. Para obtener más información acerca de la clasificación de variables y otras restricciones en las iteraciones de bucle de parfor, consulte "Clasificación de variables" en la documentación de Parallel Computing Toolbox.

¿Alguna idea de cómo solucionar esto?

Gracias!

Respuesta

7

Como se ha mencionado por @Chris, la línea

corners(1:length(y),:,i) = [y x]; 

es el problema. Una manera fácil de asegurarse de que las esquinas se puede rebanar es utilizar una matriz de células

max_pts = 900; 
cornerCell = cell(size(images,3),1); 
parfor i = 1:size(images,3) 
    I = images(:,:,i); 
    [y x] = get_corners(I,max_pts); 
    cornerCell{i} = [y x]; 
end 

Si no desea esquinas para ser un conjunto de celdas (tenga en cuenta que para trazar curvas de la imagen ITH, puede llamar imshow(images(:,:,i),[]),hold on, plot(cornerCell{i}(:,1),cornerCell{i}(:,2),'o')) , siempre se puede convertir de nuevo a su matriz original 900-por-2-por-nImages en un bucle que no le costará cualquier momento notable:

corners = zeros(max_pts,2,size(images,3)); 
for i=1:size(images,3) 
    corners(1:size(cornerCell{i},1),:,i) = cornerCell{i}; 
end 
+0

¿es posible ampliar esta a n dimensiones para la matriz imágenes?Supongamos que especifica a la función que corte sobre la dimensión Mth para que obtenga la imagen (:,:, 1,1,1,1,:, 1,1,1) donde el tercer punto está en la posición Mth. – Leo

+1

@Leo: no el corte siempre estará en la última dimensión. Sin embargo, con 'permute', puede mover las dimensiones según sea necesario. – Jonas

2

En primer lugar:

corners(1:length(y),:,i) = [y x]; 

Esa es la línea problema.

¿Leyó la documentación?

http://www.mathworks.com/help/toolbox/distcomp/brdqtjj-1.html#bq_tcng-1

Forma de Array - Al asignar a una variable en rodajas, el lado derecho de la asignación no es [] o '' (estos operadores indican supresión de elementos).

Forma de matriz. Una variable cortada debe mantener una forma constante. La variable A que se muestra aquí en cualquiera de las líneas no está cortada:

A (i, :) = []; A (extremo + 1) = i;

La razón por la que A no se divide en ninguno de los casos es porque cambiar la forma de una matriz cortada violaría las suposiciones que rigen la comunicación entre el cliente y los trabajadores.

No tengo una idea clara de lo que son x y y, pero ahora debería quedar claro cuál es el problema. ¿Puedes volver a escribir esto para que no estés asignando [] a la porción?