2010-07-16 4 views
1

Так что я пытаюсь сделать с этим кодом найти все пиксели на линии изображения, которые ниже определенного порога. Проблема в том, что этот код выполняется в цикле double for (да, я знаю :(), один раз для каждого пикселя, поэтому он очень медленный. Мне интересно, есть ли что-нибудь еще, что я могу сделать.Может ли этот фрагмент шрифта matlab быть векторизован далее?

Некоторые советы были бы замечательными, так как я довольно новичок в оптимизации MATLAB, и я знаю только основы (старайтесь не использовать циклы или многократно вызывать скрипты во внутренних функциях и т. Д.). Если это не сработает, я возможно, придется прибегнуть к MEX файлы, и это будет труднее поддерживать для других исследователей в моей группе. Спасибо!

for y = 1:y_len 
    for x = 1:x_len 
     %//...do stuff to calc slope and offset for the line, 
       %//this can be vectorized pretty easily. 

     yIndices = xIndices.*slope + offset; 
     yIndices = round(yIndices); 

     yIndices = yIndices + 1; 
     xIndices = xIndices + 1; 
     valid_points = (yIndices <= 308) & (yIndices > 0); 

     %this line is bottle necking---------------------------------------- 
     valid_points = yIndices(valid_points)+(xIndices(valid_points)-1)*308; 
     %------------------------------------------------------------------- 

     valid_points = valid_points(phaseMask_R(valid_points)); 
     t_vals = abs(phase_R(valid_points)-currentPhase); 
     point_vals = [XsR(valid_points);YsR(valid_points)] - 1; 
     matchedPtsCoordsR = point_vals(:,(t_vals<phaseThreshold) |(abs(192-t_vals)<phaseThreshold)); 

     matchedIndex = size(matchedPtsCoordsR,2); 
     if(matchedIndex ==0) 
      continue 
     end 

     centersMinMaxR = zeros(1,matchedIndex); 
     cmmIndexR = 1; 
     for a = 1:matchedIndex; 
      if(a==1) 
      avgPosition = matchedPtsCoordsR(:,a); 
      centersMinMaxR(1,1) =1; 
      else 
      currentPosition = matchedPtsCoordsR(:,a); 


      %also very slow---------------------------------------------- 
      distance = sum(abs(currentPosition-avgPosition)); 
      %------------------------------------------------------------ 
      if(distance>4) % We are now likely in a different segment. 
       centersMinMaxR(2,cmmIndexR) = a-1; 
       cmmIndexR = cmmIndexR + 1; 
       centersMinMaxR(1,cmmIndexR) = a; 
      end 
      avgPosition = matchedPtsCoordsR(:,a); 
      end 
     end 

     centersMinMaxR(2,cmmIndexR) = a; 
     centersR = round(sum(centersMinMaxR)/2); 

     %//...do stuff with centersR 
        %//I end up concatenating all the centersR into a 
        %//large vector arrray with the start and end of 
        %//each segment. 

ответ

1

во-первых, MatLab Profiler является вашим лучшим другом, и я предполагаю, что вы знаете о это потому, что вы знаете, какая линия является вырезом бутылки.

Быстрое исправление для удаления двойной петли заключается в использовании команды :. Вместо использования двойного цикла вы можете использовать один цикл, но вычислять по всему измерению для каждого индекса строки или столбца. Для простого примера:

m = magic(2); 
slope = 5; 

m = 
    1  3 
    4  2 

m(1,:) * slope = 
    5 15 

m(:,1) * slope = 
    5 
    20 

Вместо того, чтобы использовать неровные массивы, использовать разреженные массивы. Matlab имеет встроенную поддержку для них:

Matlab Create Sparse Array

Matlab Sparse Matrix Operations

UPDATE

В связи с про-минусы использования разреженного против нормального массива: Sparse vs Normal Array Matlab

Редкие матрицы - настоящее благо для человек, который использует по-настоящему разреженные матрицы, но 25% non-zeros просто не «разреженный» достаточно для любого усиления в в большинстве случаев.

Посмотрите больше обновлений, как у меня есть больше времени, чтобы проанализировать код: р

+0

Спасибо за ответ! Некоторые из проблем, с которыми я сталкиваюсь в векторизации, заключаются главным образом в том, что я не уверен, сколько у меня очков для каждого пикселя, а массивы с зубчатым колесом на самом деле не поддерживаются – Xzhsh

+0

@Xzhsh, вместо массивных массивов создавайте разреженные массивы , Matlab имеет встроенную поддержку редких массивов http://www.mathworks.com/access/helpdesk/help/techdoc/ref/sparse.html http://www.mathworks.com/access/helpdesk/help /techdoc/math/f6-8856.html – Elpezmuerto

+0

В какой момент имеется разреженный массив лучше обычного массива, если у меня все еще есть много вычислений, и около 25% массива не нули? – Xzhsh