2010-07-16 8 views
1

Donc, ce que j'essaie de faire avec ce code, c'est de trouver tous les pixels sur une ligne d'une image qui sont en dessous d'un certain seuil. Le problème, cependant, est que ce code est exécuté dans un double pour boucle (ouais je sais :(), une fois pour chaque pixel, donc c'est très lent, je me demande s'il y a autre chose que je peux faireEst-ce que cette partie du script matlab peut être vectorisée plus loin?

Certains conseils seraient super, car je suis assez nouveau pour l'optimisation de MATLAB, et je ne connais que les bases (essayez de ne pas utiliser de boucles, ou appelez des scripts plusieurs fois dans les fonctions internes, etc) Si cela ne fonctionne pas, je pourrait avoir recours à des fichiers MEX, et ce sera plus difficile à maintenir pour les autres chercheurs de mon groupe. Merci!

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. 

Répondre

1

Tout d'abord, MatLab Profiler est votre meilleur ami et je suppose que vous connaissez parce que vous savez quelle ligne est la bouteille de rétreint

Une solution rapide pour supprimer la double boucle consiste à utiliser la commande :. Au lieu d'utiliser une double boucle, vous pouvez utiliser une seule boucle, mais calculer le long d'une dimension entière pour chaque index de ligne ou de colonne. Pour un exemple simple:

m = magic(2); 
slope = 5; 

m = 
    1  3 
    4  2 

m(1,:) * slope = 
    5 15 

m(:,1) * slope = 
    5 
    20 

Au lieu d'utiliser des matrices dentelées, utilisez des matrices creuses. Matlab a un support intégré pour eux:

Matlab Create Sparse Array

Matlab Sparse Matrix Operations

MISE À JOUR

En ce qui concerne les pro-contre l'utilisation d'un clairsemés vs tableau normal: Sparse vs Normal Array Matlab

Les matrices éparses sont un véritable avantage pour la personne qui utilise vraiment matrices, mais 25% non-zéros est simplement pas "assez" assez pour tout gain dans la plupart des cas.

Rechercher des mises à jour plus comme je l'ai plus de temps pour vérifier votre code: p

+0

Merci pour la réponse! Certains des problèmes que j'ai avec la vectorisation résident principalement dans le fait que je ne suis pas sûr du nombre de points que je vais avoir pour chaque pixel, et que les tableaux dentelés ne sont pas vraiment supportés – Xzhsh

+0

@Xzhsh, au lieu du tableau jagged créer des tableaux clairsemés . Matlab prend en charge les baies clairsemées 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

A quel point est-il préférable d'avoir un tableau clairsemé qu'un tableau normal si j'ai encore beaucoup de calculs à faire, et environ 25% du tableau ne sont pas des zéros? – Xzhsh