Pergunta

Estou começando a programação em MATLAB e tenho alguns problemas criando uma matriz de buffer. Eu estou tentando fazer o seguinte:

Eu estou obtendo continuamente uma imagem de uma webcam e depois de segmentação I obter o centróide de um alvo em movimento. Eu preciso armazenar os dados centróide para processamento, mas eu não quero que ocupam muita memória. Por exemplo, se eu fosse um t=inf tempo, eu estava pensando de armazenar 10 pontos temporais de dados em uma matriz, como um buffer circular, em seguida, escrever e apagar os dados mais velhos, porque eu preciso trabalhar com ambos, os dados reais no tempo ( t) e um conjunto de dados anterior no tempo (t-1).

Foi útil?

Solução

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

Eu testei isso, não tem tempo apreciável para ser executado no MATLAB. O profiler não encontrou os gargalos com o código.

Outras dicas

UPDATE:

Uma vez que agora eu entendo que você precisa de um circular de buffer para armazenar dados, aqui está uma solução que você pode usar. Desde que disse que foram armazenar dados centróide de objectos numa imagem, que vai dar-lhe um processo geral para o armazenamento de um número arbitrário de medições (quer um valor de índice de pixel para cada centróide, ou 2 valores de coordenadas x e y, etc) ...

Em primeiro lugar, inicializar o buffer:

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

Em seguida, você vai ter o seu ciclo contínuo. Você pode usar um enquanto loop e uma variável de sinalizador que inicialmente tem o valor VERDADEIRO (e que você pode definir a FALSE para parar o loop):

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

Isso funciona da seguinte forma: em cada ponto de tempo, a primeira coluna (ou seja, os dados anteriores) em centroidBuffer é removida e uma nova coluna (isto é, os novos dados) é anexado ao fim . Desta maneira, a matriz de tampão é sempre o mesmo tamanho.

Se você não quiser realizar o processamento em cada passo de tempo, mas em vez disso só depois de todos os nBuffer pontos tempo para que ele está operando em um novo conjunto de dados de cada vez, em seguida, substituir o acima de código com o seguinte:

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:

Há uma série de variações que você pode fazer com o código acima. Por exemplo, se você deseja armazenar dois conjuntos de dados com 10 pontos no tempo cada um, você pode mudar nBuffer a 20 para armazenar o antigo conjunto nos primeiros 10 colunas e o novo conjunto nos últimos 10 colunas . Em seguida, altere a declaração se a:

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

E agora você pode realizar o seu processamento usando tanto o conjunto mais antigo de 10 pontos de dados (em centroidBuffer (:, 1:10) ) e o conjunto mais recente de 10 pontos de dados (em centroidBuffer (:, 11:20). )

Quando você está falando de grandes conjuntos de dados em cada iteração, o shuffle de dados pode começar a tomar um pouco de tempo. A maneira que eu lidar com isso para grandes conjuntos de dados é usar algo como:

circBuff (:,:, modificação (contador, numFrames)) = newData; Desta forma, você apenas os dados de substituição uma vez, ao invés de mover todos os pontos de dados em todo o seu tampão em cada ciclo. Você apenas tem que ser um pouco mais esclarecido sobre como você acessar seus dados.

HTH, Dan

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

Esta é uma solução agradável e simples, mas é lento. Toda vez que você adicionar um novo vetor, Matlab tem que copiar os dados inteiros de idade, exceto a primeira entrada. Se você pensar em tempo real, isso não é uma boa idéia.

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

Esta ideia não tem a cópia de problemas, mas agora você não tem uma boa subarray mais, o que representa desde o primeiro índice para o último índice os dados em ordem cronológica.

I acabou de enviar minha solução para um buffer rápido circular que evita os dois problemas para

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

A idéia principal deste buffer circular é constante e rápido desempenho e evitando operações de cópia ao usar o tampão em um programa:

% 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));

Verifique a tela para ver, que este buffer circular tem vantagens se o buffer é grande, mas o tamanho dos dados para acrescentar cada vez é pequeno como o desempenho de circVBuf não depende do tamanho do buffer, em comparação com uma cópia simples tampão.

O buffer duplo Garanties um tempo previsível para um acréscimo acordo com os dados para anexar em qualquer situação. No futuro, esta classe deve dar-lhe uma escolha para sim buffer duplo ou não - as coisas vão speedup, se você não precisa o tempo garantied. enter descrição da imagem aqui

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top