Создайте буферную матрицу для непрерывных измерений

StackOverflow https://stackoverflow.com/questions/821637

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

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

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

Другие советы

Обновить:

Поскольку теперь я понимаю, что вам нужен круглый буфер для хранения данных, вот решение, которое вы можете использовать.Поскольку вы сказали, что сохраняете данные центроида объектов на изображении, я приведу вам общий случай сохранения произвольного количества измерений (либо 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 и переменная flag, которая изначально имеет значение ВЕРНО (и который вы можете установить на ЛОЖЬ чтобы остановить цикл):

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

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

Если вы не хотите выполнять обработку на каждом временном шаге, а вместо этого только после каждого 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

Редактировать:

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

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

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

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

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

ХТХ, Дан

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

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

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

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

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

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

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

% 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 НЕ зависит от размера буфера по сравнению с простой копией буфер.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top