문제

Matlab에서 프로그래밍을 시작하고 버퍼 매트릭스를 만드는 데 몇 가지 문제가 있습니다. 나는 다음을하려고 노력하고있다 :

나는 웹캠에서 이미지를 지속적으로 얻고 있으며 세분화 후 움직이는 대상의 중심을 얻습니다. 처리를 위해 중심 데이터를 저장해야하지만 너무 많은 메모리를 점유하고 싶지는 않습니다. 예를 들어, 내가 시간 이었다면 t=inf, 나는 원형 버퍼와 같은 매트릭스에 10 개의 시점의 데이터를 저장 한 다음 오래된 데이터 (t) 및 이전 데이터와 함께 작업해야하기 때문에 이전 데이터를 작성하고 지우려는 생각을하고있었습니다 (time in time). T-1).

도움이 되었습니까?

해결책

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

나는 이것을 테스트했지만 Matlab에서 달리는 데는 시간이 걸리지 않습니다. 프로파일 러는 코드와 병목 현상을 찾지 못했습니다.

다른 팁

업데이트:

이제 나는 당신이 필요하다는 것을 이해하기 때문에 회보 버퍼 데이터를 저장하려면 여기에 사용할 수있는 솔루션이 있습니다. 이미지에 객체의 중심 데이터를 저장하고 있다고 말 했으므로 임의의 측정 수를 저장할 수있는 일반적인 사례를 제공합니다 (각 중심에 대한 1 픽셀 인덱스 값 또는 X 및 Y 좌표의 2 값 등). ...

먼저 버퍼를 초기화합니다.

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

다음으로 연속 루프가 있습니다. 당신은 a를 사용할 수 있습니다 루프 중 그리고 처음에는 값이있는 플래그 변수입니다 진실 (그리고 당신이 설정할 수있는 거짓 루프를 중지하려면) :

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

편집하다:

위의 코드에서 만들 수있는 여러 가지 변형이 있습니다. 예를 들어, 각각 10 개의 시점이있는 두 개의 데이터 세트를 저장하려면 변경할 수 있습니다. Nbuffer 기존 세트를 처음 10 개의 열에 저장하고 마지막 10 개의 열에 새 세트를 저장합니다. 그런 다음 if 문을 다음과 같이 변경합니다.

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

이제 10 개의 구형 데이터 포인트 세트를 사용하여 처리를 수행 할 수 있습니다 ( CentroidBuffer (:, 1:10)) 및 최신 10 개의 데이터 포인트 세트 ( CentroidBuffer (:, 11:20)).

각 반복마다 큰 데이터 세트에 대해 이야기 할 때 데이터 셔플이 시간을 내기 시작할 수 있습니다. 큰 데이터 세트를 위해 처리하는 방식은 다음과 같은 것을 사용하는 것입니다.

Circbuff (:, :, mod (Coun 이렇게하면 각주기에서 전체 버퍼의 모든 데이터 포인트를 이동하는 대신 데이터를 한 번만보고합니다. 데이터에 액세스하는 방법에 대해 조금 더 정통해야합니다.

HTH, 댄

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top