문제
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의 성능이 버퍼 크기에 의존하지 않기 때문에 매번 추가 할 데이터의 크기가 작습니다.
이중 버퍼링은 모든 상황에서 추가로 데이터에 따라 추가되는 예측 시간입니다. 미래 에이 수업은 이중 버퍼링 예 또는 아니오를 선택할 수 있습니다.