2009-05-04 8 views
3

Je commence la programmation dans MATLAB et j'ai quelques problèmes pour créer une matrice tampon. J'essaye de faire ce qui suit:Créer une matrice tampon pour les mesures en continu

J'obtiens continuellement une image d'une webcam et après la segmentation j'obtiens le centroïde d'une cible mobile. J'ai besoin de stocker les données du centroïde pour le traitement mais je ne veux pas qu'il occupe trop de mémoire. Par exemple, si j'étais un temps t=inf, je pensais stocker 10 points temporels de données dans une matrice, comme un tampon circulaire, puis écrire et effacer les anciennes données, parce que j'ai besoin de travailler avec les deux, les données réelles dans le temps (t) et une donnée précédente dans le temps (t-1).

+0

J'ai essayé de clarifier la question avec l'information supplémentaire que vous m'avez donnée. Si vous n'aimez pas les mises à jour, n'hésitez pas à les annuler. Je pensais juste que cela pourrait être plus clair. =) – gnovice

Répondre

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

Je l'ai testé, cela ne prend pas beaucoup de temps pour fonctionner dans MATLAB. Le profileur n'a trouvé aucun goulot d'étranglement avec le code.

2

MISE À JOUR:

Depuis que je comprends maintenant que vous avez besoin d'un tampon circulaire pour stocker des données, voici une solution que vous pouvez utiliser. Puisque vous avez indiqué que vous stockez 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 1 valeur d'index pour chaque centroïde, soit 2 valeurs pour les coordonnées x et y, etc.) ...

D'abord, initialiser 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. Vous pouvez utiliser un while loop et une variable de drapeau qui a d'abord la valeur TRUE (et que vous pouvez définir à 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 point de temps, le premier colonne (c.-à-d. les données les plus anciennes) dans centroidBuffer est supprimé et une nouvelle colonne (c.-à-d. les nouvelles données) est ajoutée à la fin. De cette façon, la matrice tampon est toujours de la même taille.

Si vous ne souhaitez pas effectuer votre traitement à chaque pas de temps, mais seulement après chaque nBuffer points de pointage afin qu'il fonctionne à chaque fois sur un nouveau jeu de données, remplacez le code ci-dessus par le suivant:

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 y a un certain nombre de variations que vous pouvez faire avec le code ci-dessus. Par exemple, si vous voulez stocker deux ensembles de données avec 10 points de temps chacun, vous pouvez modifier nBuffer à 20 pour stocker l'ancien ensemble dans les 10 premières colonnes et le nouvel ensemble dans les 10 dernières colonnes. Ensuite, modifiez l'instruction if:

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

Et maintenant, vous pouvez effectuer votre traitement utilisant à la fois l'ensemble plus de 10 points de données (en centroidBuffer (:, 01:10)) et l'ensemble des 10 plus récents points de données (dans centroidBuffer (:, 11:20)).

+0

Merci gnovice pour votre suggestion, désolé je n'étais pas clair, j'obtiens une image de la webcam et après la segmentation l'objectif est d'obtenir et de suivre le centroïde de la cible en mouvement, j'ai besoin de stocker son centroïde pour le traitement et l'application filtre kalman, mon temps t = inf pas 100, une suggestion pour stocker mes données, mais ne pas occuper beaucoup de mémoire?, je pensais dans une matrice de stockage de données 10 fois, comme un tampon circulaire, écrire et effacer l'ancien temps de données. J'espère que tu me comprends – carlos

+0

Ahh, maintenant je comprends que tu devras avoir un tampon circulaire. Je mettrai à jour ma réponse pour vous aider dans ce cas spécifique. – gnovice

2

Lorsque vous parlez de grands ensembles de données à chaque itération, le mélange de données peut prendre du temps. La façon dont je le gère pour les grands ensembles de données est d'utiliser quelque chose comme:

circBuff (:,:, mod (compteur, numFrames)) = newData; De cette façon, vous écrasez les données une seule fois, plutôt que de déplacer chaque point de données dans votre tampon entier à chaque cycle. Vous devez juste être un peu plus avertis sur la façon dont vous accédez à vos données.

HTH, Dan

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

C'est une solution simple et agréable, mais il est lent. Chaque fois que vous ajoutez un nouveau vecteur, matlab doit copier toutes les anciennes données sauf 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-copie, mais maintenant vous n'avez pas une belle plus sous-tableau, qui représente le premier indice au dernier indice des données dans l'ordre chronologique.

Je viens uploadé ma solution pour un tampon circulaire rapide qui évite les deux problèmes à

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

L'idée principale de ce tampon circulaire est constante et des performances rapides et en évitant 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, que ce tampon circulaire présente des avantages si le tampon est grande, mais la taille des données à Greffer chaque tim e est petit car les performances de circVBuf ne dépendent PAS de la taille du tampon, comparé à un simple tampon de copie. Le double tampon garantit un temps prédictif pour un ajout en fonction des données à ajouter dans n'importe quelle situation. À l'avenir, cette classe vous donnera le choix entre deux tampons oui ou non - les choses vont accélérer, si vous n'avez pas besoin du temps garanti. enter image description here

Questions connexes