MATLAB Parfor вопрос нарезки? - PullRequest
8 голосов
/ 06 марта 2011

У меня есть фрагмент кода, который находит углы Харриса в последовательности изображений.Мне нужно сделать это для 92 изображений, но это довольно медленно.Поэтому я хотел бы запустить код параллельно.В приведенном ниже коде есть ошибка, связанная с переменной «углы»

%% 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

, которая гласит:

MATLAB запускает циклы в функциях parfor, разделяя итерации цикла на группы, а затем отправляяих работникам MATLAB, где они работают параллельно.Чтобы MATLAB делал это надежным и воспроизводимым способом, он должен иметь возможность классифицировать все переменные, используемые в цикле.Код использует указанную переменную таким образом, который несовместим с классификацией.Предлагаемое действие Исправьте использование указанной переменной.Для получения дополнительной информации о классификации переменных и других ограничениях на итерации цикла parfor см. «Классификация переменных» в документации по Parallel Computing Toolbox.

Есть идеи, как это исправить?

Спасибо!

Ответы [ 2 ]

8 голосов
/ 06 марта 2011

Как упомянуто @ Крис , строка

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

это проблема. Простой способ убедиться, что углы срезаются, - использовать массив ячеек

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

Если вы не хотите, чтобы углы были массивом ячеек (обратите внимание, что для построения углов для i-го изображения вы можете вызвать imshow(images(:,:,i),[]),hold on, plot(cornerCell{i}(:,1),cornerCell{i}(:,2),'o')), вы всегда можете преобразовать обратно в исходный формат 900 на 2 на 2 Массив nImages в цикле, который не будет стоить вам заметного времени:

corners = zeros(max_pts,2,size(images,3));
for i=1:size(images,3)
   corners(1:size(cornerCell{i},1),:,i) = cornerCell{i};
end
2 голосов
/ 06 марта 2011

Сначала:

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

В этом проблема.

Вы читали документацию?

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

Shape of Array - При назначении нарезанной переменной правой частью назначения не является [] или '' (эти операторы указывают на удаление элементов).

Форма массива. Нарезанная переменная должна поддерживать постоянную форму. Переменная A, показанная здесь в любой строке, не разрезана:

A (i, :) = []; A (конец + 1) = i;

Причина того, что A не разрезана ни в одном из случаев, заключается в том, что изменение формы выделенного массива нарушило бы предположения, регулирующие взаимодействие между клиентом и работниками.

Я не очень хорошо понимаю, что такое x и y, но теперь должно быть понятно, в чем проблема. Можете ли вы переписать это так, чтобы не назначать [] для среза?

...