2009-05-04 3 views
3

MATLAB에서 프로그래밍을 시작할 때 버퍼 매트릭스 생성에 문제가 있습니다. 다음 작업을 수행하려고합니다.연속 측정을위한 버퍼 매트릭스 만들기

웹캠에서 이미지를 연속적으로 얻고 분할 한 후에 움직이는 표적의 중심을 얻습니다. 처리를 위해 중심 데이터를 저장해야하지만 너무 많은 메모리를 차지하지는 않습니다. 예를 들어 내가 시간이 t=inf이라면 원형 버퍼와 같은 매트릭스에 10 개의 데이터 포인트 포인트를 저장하고 이전 데이터를 쓰고 지우는 것을 생각하고있었습니다. 왜냐하면 둘 다 작업해야하기 때문에 실제 데이터는 시간적으로 (t)와 이전 데이터 (t-1)를 비교한다.

+0

나는 당신이 나에게 준 추가 정보로 질문을 명확히하려고 노력했다. 업데이트가 마음에 들지 않으면 자유롭게 업데이트를 취소하십시오. 방금 이것이 더 명확해질 수 있다고 생각했습니다. =) – gnovice

답변

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

나는 이것을 테스트했지만, MATLAB에서 실행하는 데 상당한 시간이 걸리지 않습니다. 프로파일 러는 코드에 병목 현상을 발견하지 못했습니다.

2

UPDATE : 지금 데이터를 저장하는 원형 버퍼를 필요로 이해하기 때문에

, 여기 당신이 사용할 수있는 솔루션입니다. 이미지의 객체 중심 데이터를 이미지에 저장한다고 했으므로 임의의 수의 측정 값 (각 중심에 대해 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 

다음, 당신은 당신의 연속 루프를해야합니다. (루프를 중지하고 당신은 FALSE에 설정할 수있는) 당신은 초기 값 TRUE이있는 while 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 

를 각 시점에서, 첫 번째 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을 20으로 변경하여 처음 10 개 열에 이전 세트를 저장하고 마지막 10 개 열에 새 세트를 저장합니다. 그런 다음에 if 문 변경 :

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

을 그리고 지금은 (centroidBuffer (에 : 1:10)) 10 데이터 포인트의 이전 설정을 모두 사용하여 처리를 수행 할 수있는 10의 새로운 세트 데이터 포인트 (centroidBuffer (:, 11:20)).

+0

당신의 제안에 감사드립니다, 미안 해요, 웹캠에서 이미지를 얻고 있습니다. 목표를 얻고 세분화 한 후에 목표 이동의 중심을 따라 가면 처리 및 적용을 위해 중심점 (위치)을 저장해야합니다. 칼만 필터, 내 시간 t = inf 100 아니, 내 데이터를 저장하기위한 제안하지만 많은 메모리를 차지하지?, 나는 순환 버퍼와 같은 행렬 저장소 데이터를 10 번 생각하고, 이전 데이터 시간을 작성하고 지 웁니다. 나는 당신이 나를 이해하기를 바랍니다. – carlos

+0

아, 이제는 순환 버퍼가 있어야한다는 것을 이해합니다. 나는 그 특정한 경우에 당신을 도울 내 대답을 업데이 트합니다. – gnovice

2

각 반복에서 대용량 데이터 세트에 대해 이야기 할 때 데이터 셔플은 다소 시간이 걸릴 수 있습니다. 큰 데이터 세트를 처리하는 방법은 다음과 같이 사용하는 것입니다.

circBuff (:, :, mod (counter, numFrames)) = newData; 이 방법을 사용하면 각주기마다 전체 버퍼에서 모든 데이터 요소를 이동하지 않고 데이터를 한 번만 덮어 씁니다. 데이터에 액세스하는 방법에 대해 좀 더 정통해야합니다.

HTH, 댄

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

이것은 좋은 간단한 솔루션이지만 속도가 느립니다. 새 벡터를 추가 할 때마다 matlab은 첫 번째 항목을 제외한 이전 데이터 전체를 복사해야합니다. 실시간에 대해 생각한다면 이것은 좋은 생각이 아닙니다.

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

이 아이디어는 복사 문제가되지 않지만, 지금은 마지막 인덱스 연대순으로 데이터에 대한 최초의 인덱스에서 나타내는 더 멋진 부분 배열을 필요가 없습니다.

I는 버퍼를 사용하는 경우

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의 성능이 간단한 복사 버퍼에 비해 버퍼 크기에 의존하지 않으므로 e는 작습니다.

이중 버퍼링은 임의의 상황에 추가 할 데이터에 따라 추가 시간을 보장합니다. 앞으로이 클래스는 이중 버퍼링 예 또는 아니오에 대한 선택권을 제공합니다 - 보장 된 시간이 필요하지 않으면 사태가 빨라질 것입니다. enter image description here