Создать буферную матрицу для непрерывных измерений - PullRequest
3 голосов
/ 04 мая 2009

Я начинаю программировать в MATLAB, и у меня возникают проблемы с созданием буферной матрицы. Я пытаюсь сделать следующее:

Я непрерывно получаю изображение с веб-камеры, и после сегментации я получаю центроид движущейся цели. Мне нужно хранить данные центроида для обработки, но я не хочу, чтобы они занимали слишком много памяти. Например, если бы я был временем t=inf, я думал о том, чтобы сохранить 10 временных точек данных в матрице, например, в кольцевом буфере, затем записать и стереть более старые данные, потому что мне нужно работать с обоими, фактическими данными в время (t) и предыдущие данные во времени (t-1).

Ответы [ 4 ]

7 голосов
/ 05 мая 2009
buffSize = 10;
circBuff = nan(1,buffSize);
for newest = 1:1000;
    circBuff = [newest circBuff(1:end-1)]
end

Я проверил это, для запуска в MATLAB не требуется заметного времени. Профилировщик не нашел узких мест с кодом.

2 голосов
/ 05 мая 2009

Когда вы говорите о больших наборах данных на каждой итерации, перестановка данных может начать занимать некоторое время. То, как я справляюсь с этим для больших наборов данных, использует что-то вроде:

circBuff (:,:, mod (counter, numFrames)) = newData; Таким образом, вы перезаписываете данные только один раз, а не перемещаете каждую точку данных во всем буфере в каждом цикле. Вы просто должны быть немного более осведомлены о том, как вы получаете доступ к своим данным.

НТН, Dan

2 голосов
/ 05 мая 2009

UPDATE:

Поскольку теперь я понимаю, что вам нужен циклический буфер для хранения данных, вот решение, которое вы можете использовать. Поскольку вы сказали, что храните данные центроидов объектов на изображении, я дам вам общий случай для хранения произвольного числа измерений (либо значение индекса в 1 пиксель для каждого центроида, либо 2 значения для координат x и y и т. Д.) ...

Сначала инициализируйте буфер:

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

Далее у вас будет непрерывный цикл. Вы можете использовать while loop и переменную флага, которая изначально имеет значение TRUE (и которую вы можете установить на FALSE , чтобы остановить цикл):

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

Это работает следующим образом: в каждый момент времени первый столбец (т. Е. Самые старые данные) в centroidBuffer удаляется, а новый столбец (т. Е. Новые данные) добавляется в конец. Таким образом, буферная матрица всегда имеет одинаковый размер.

Если вы не хотите выполнять обработку на каждом временном шаге, а вместо этого только после каждых nBuffer временных точек, чтобы он каждый раз работал с новым набором данных, то замените вышеуказанный код со следующим:

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:

Есть несколько вариантов, которые вы можете сделать с помощью приведенного выше кода. Например, если вы хотите сохранить два набора данных с 10 временными точками каждый, вы можете изменить nBuffer на 20, чтобы сохранить старый набор в первых 10 столбцах и новый набор в последних 10 столбцах. Затем измените оператор if на:

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

И теперь вы можете выполнять обработку, используя как старый набор из 10 точек данных (в centroidBuffer (:, 1:10) ), так и более новый набор из 10 точек данных (в centroidBuffer (:, 11: 20). * * одна тысяча сорок-три)

1 голос
/ 21 июня 2014
centroidBuffer = [centroidBuffer(:,2:end) centroidData(:)];

Это хорошее и простое решение, но оно медленное. Каждый раз, когда вы добавляете новый вектор, matlab должен копировать все старые данные, кроме первой записи. Если вы думаете о реальном времени, это не очень хорошая идея.

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

Эта идея не имеет проблемы с копированием, но теперь у вас больше нет красивого подмассива, который представляет данные от первого индекса до последнего индекса в хронологическом порядке.

Я только что загрузил свое решение для быстрого кругового буфера, который позволяет избежать двух проблем, до

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

Основная идея этого циклического буфера - постоянная и быстрая производительность и избегая операций копирования при использовании буфера в программе:

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

Проверьте снимок экрана, чтобы увидеть, что этот циклический буфер имеет преимущества, если буфер большой, но размер данных, добавляемых каждый раз, невелик, поскольку производительность circVBuf НЕ зависит от размера буфера по сравнению с простой копией буфер.

Двойная буферизация обеспечивает прогнозируемое время добавления в зависимости от данных, добавляемых в любой ситуации. В будущем этот класс даст вам выбор для двойной буферизации да или нет - все ускорится, если вам не нужно гарантированное время. enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...