Question

Je commence la programmation dans MATLAB et j'ai quelques problèmes pour créer une matrice de mémoire tampon. J'essaie de faire ce qui suit:

J'obtiens continuellement une image d'une webcam et après la segmentation, j'obtiens le centre de gravité d'une cible en mouvement. Je dois stocker les données du centre de gravité pour le traitement, mais je ne veux pas qu'elles occupent trop de mémoire. Par exemple, si j’étais à l’heure t = inf , je pensais stocker 10 points temporels de données dans une matrice, comme un tampon circulaire, puis écrire et effacer les données plus anciennes, car j’avais besoin de travailler. avec les deux, les données réelles dans le temps (t) et les données précédentes dans le temps (t-1).

Était-ce utile?

La solution

buffSize = 10;
circBuff = nan(1,buffSize);
for newest = 1:1000;
    circBuff = [newest circBuff(1:end-1)]
end

J'ai testé cela, l'exécution de MATLAB ne prend pas beaucoup de temps. Le profileur n'a pas trouvé de goulot d'étranglement avec le code.

Autres conseils

UPDATE:

Comme je comprends maintenant que vous avez besoin d'un tampon circulaire pour stocker les données, voici une solution que vous pouvez utiliser. Puisque vous avez dit que vous stockiez des données centroïdes d'objets dans une image, je vais vous donner un cas général pour stocker un nombre arbitraire de mesures (soit une valeur d'indice de pixel pour chaque centroïde, ou deux valeurs pour les coordonnées x et y, etc.). ...

D'abord, initialisez le tampon:

nBuffer = 10;  % You can set this to whatever number of time points
               %   you want to store data for
nSamples = 2;  % You can set this to the number of data values you
               %   need for each point in time
centroidBuffer = zeros(nSamples,nBuffer);  % Initialize the buffer to zeroes

Ensuite, vous aurez votre boucle continue. Vous pouvez utiliser une une boucle While et une variable d'indicateur. qui a initialement la valeur TRUE (et que vous pouvez définir sur FALSE pour arrêter la boucle):

keepLooping = true;
while keepLooping,
  % Capture your image
  % Compute the centroid data and place it in the vector "centroidData"
  centroidBuffer = [centroidBuffer(:,2:end) centroidData(:)];
  % Do whatever processing you want to do on centroidBuffer
  % Choose to set keepLooping to false, if you want
end

Cela fonctionne de la manière suivante: à chaque instant, la première colonne (c.-à-d. les données les plus anciennes) dans centroidBuffer est supprimée et une nouvelle colonne (c.-à-d. les nouvelles données) est ajoutée à la fin. . De cette manière, la matrice de mémoire tampon a toujours la même taille.

Si vous ne souhaitez pas effectuer votre traitement à chaque pas de temps, mais seulement après chaque nBuffer afin qu'il opère à chaque fois sur un nouvel ensemble de données, remplacez le code ci-dessus avec les éléments suivants:

keepLooping = true;
processTime = 0;
while keepLooping,
  % Capture your image
  % Compute the centroid data and place it in the vector "centroidData"
  centroidBuffer = [centroidBuffer(:,2:end) centroidData(:)];
  processTime = processTime+1;
  if (processTime == nBuffer),
    % Do whatever processing you want to do on centroidBuffer
    processTime = 0;
  end
  % Choose to set keepLooping to false, if you want
end

EDIT:

Il existe un certain nombre de variations que vous pouvez utiliser avec le code ci-dessus. Par exemple, si vous souhaitez stocker deux jeux de données avec 10 points de temps chacun, vous pouvez remplacer nBuffer par 20 pour stocker l'ancien jeu dans les 10 premières colonnes et le nouveau jeu dans les 10 dernières colonnes. . Modifiez ensuite l'instruction if en:

  ...
  if (processTime == nBuffer/2),
  ...

Et vous pouvez maintenant effectuer votre traitement en utilisant le jeu de 10 points de données plus ancien (dans centroidBuffer (:, 1:10) ) et le jeu de 10 points de données plus récent (en centroidBuffer (:, 11:20) ).

Lorsque vous parlez de grands ensembles de données à chaque itération, le mélange de données peut commencer à prendre un certain temps. Pour les grands ensembles de données, je l’utilise comme suit:

circBuff (:,:, mod (compteur, numFrames)) = newData; De cette façon, vous écrasez les données une seule fois, au lieu de déplacer tous les points de données de votre mémoire tampon entière à chaque cycle. Vous devez juste être un peu plus avisé sur la façon dont vous accédez à vos données.

HTH, Dan

centroidBuffer = [centroidBuffer(:,2:end) centroidData(:)];

C’est une solution simple et agréable, mais lente. Chaque fois que vous ajoutez un nouveau vecteur, matlab doit copier toutes les anciennes données, à l'exception de la première entrée. Si vous pensez en temps réel, ce n'est pas une bonne idée.

circBuff(:,:,mod(counter,numFrames)) = newData

Cette idée n’a pas le problème de la copie, mais vous n’avez plus un beau sous-tableau, qui représente du premier au dernier index les données dans l’ordre chronologique.

Je viens de télécharger ma solution pour un tampon circulaire rapide qui évite les deux problèmes de

http://www.mathworks.com/matlabcentral/fileexchange/47025 -circvbuf-m

L’idée principale de ce tampon circulaire est une performance constante et rapide et éviter les opérations de copie lors de l'utilisation du tampon dans un programme:

% create a circular vector buffer
    bufferSz = 1000;
    vectorLen= 7;
    cvbuf = circVBuf(int64(bufferSz),int64(vectorLen));

% fill buffer with 99 vectors
    vecs = zeros(99,vectorLen,'double');
    cvbuf.append(vecs);

% loop over lastly appended vectors of the circVBuf:
    new = cvbuf.new;
    lst = cvbuf.lst;
    for ix=new:lst
       vec(:) = cvbuf.raw(:,ix);
    end

% or direct array operation on lastly appended vectors in the buffer (no copy => fast)
    new = cvbuf.new;
    lst = cvbuf.lst;
    mean = mean(cvbuf.raw(3:7,new:lst));

Vérifiez la capture d'écran pour voir si ce tampon circulaire présente des avantages si le tampon est volumineux, mais que la taille des données à ajouter à chaque fois est petite, car les performances de circVBuf NE dépendent PAS de la taille du tampon, comparé à une copie simple. tampon.

Le double tampon garantit un temps prédictif pour un ajout en fonction des données à ajouter dans toutes les situations. À l'avenir, cette classe vous donnera le choix entre double tampon, oui ou non - les choses s'accéléreront si vous n'avez pas besoin du temps garanti. entrer la description de l'image ici

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top