2013-05-10 2 views
0

Я пытаюсь сэкономить время вычисления. Я выполняю обработку изображений с помощью известного алгоритма Лукаса Канаде. Отправной точкой была эта статья: Baker/Simon.Исключить матричные элементы из расчета по производительности

Я делаю это Matlab, и я также использую вспомогательный субстрат. Я хочу, чтобы вычитатель устанавливал весь фон в 0 или имел логическую маску с 1 как передний план и 0 в качестве фона.

Что я хочу, это исключить все элементы матрицы, которые являются фоном из расчета. Моя цель - сэкономить время для расчета. Я знаю, что я могу использовать синтаксис как

A(A>0) = ... 

Но это не работает так, как

B(A>0) = A.*C.*D 

, потому что я получаю сообщение об ошибке:

В назначениях (I) = B, количество элементов в B и I должно быть одинаковым.

Это, вероятно, потому, что А, В и С, все вместе имеют больше элементов, чем только матрицы А.

В C-кода я бы просто цикл матрица и проверить, если пиксель имеет значение 0, и продолжить , В этом случае сохраните целую кучу вычислений.

В Matlab, однако, не очень быстро пройти через матрицу. Так есть быстрый способ решить мою проблему? Я не мог найти достаточного ответа на мою проблему здесь.

В любом случае меня интересует: Я пытаюсь использовать надежную функцию ошибки вместо квадратичных.

Update:

Я пробовал следующий подход для проверки скорости, как было предложено @Acorbe:

function MatrixTest() 
n = 100; 
A = rand(n,n); 
B = rand(n,n); 
C = rand(n,n); 
D = rand(n,n); 

profile clear, profile on; 
for i=1:10000  
    tests(A,B,C,D); 
end 
profile off, profile report; 

function result = tests(A,B,C,D) 
    idx = (B>0); 

    t = A(idx).*B(idx).*C(idx).*D(idx); 
    LGS1a(idx) = t; 

    LGS1b = A.*B.*C.*D; 

И я получил результаты folloing с профилировщика: MATLAB

t = A(idx).*B(idx).*C(idx).*D(idx); 1.520 seconds 
LGS1a(idx) = t; 0.513 seconds 
idx = (B>0);  0.264 seconds 
LGS1b = A.*B.*C.*D; 0.155 seconds 

Как вы можете видеть, накладные расходы на доступ к матрице по индексу намного дороже, чем просто

ответ

0

Как насчет следующего?

mask = A>0; 

B = zeros(size(A)); % # some initialization 

t = A.*C.*D; 
B(mask) = t(mask); 

таким образом вы выбираете только необходимые элементы t. Возможно, в расчете есть некоторые накладные расходы, хотя они, вероятно, незначительны по отношению к медлительности циклов.


EDIT:

Если вы хотите больше скорости, вы можете попробовать более избирательный подход, который использует маску везде.

t = A(mask).*C(mask).*D(mask); 
B(mask) = t; 
+0

Спасибо за комментарий, но за t = A. * C. * D Я бы все равно выполнил расчеты. Это то, что я пытаюсь предотвратить.Может быть, мне нужно было сказать, что A, B, C, D имеют одинаковый размер, и эти матрицы зависят друг от друга. Поэтому, если мне не нужен элемент в точке A (x, y), то мне не нужно вычислять в точке A (x, y) * C (x, y) * D (x, y). Это накладные расходы, о которых вы говорите, важно, потому что я буду делать умножения сто раз, и я хочу их как можно быстрее в Matlab. –

+0

@ SebastianSchütze, пожалуйста, внесите обновленный ответ. – Acorbe

+0

Обновлен мой ответ. –

Смежные вопросы