aviread and mmread memory usage
이전 댓글 표시
I want to process images frame by frame using aviread or mmread and then save the processed images as a new movie. I have preallocated the structure array for the frames without memory issues,
D(1:nFrames) = struct('cdata', ones(vidHeight, vidWidth, 3, 'uint8'),'colormap', []);
but as the loop runs aviread and mmread use up all the memory even though they are not storing any new variables (that I can see). When it reaches frame 420 out of 1444 (1024x1024x3 colordata) it fails with:
??? The file could not be read. (Ran out of memory ) Error in ==> mmreader.read at 74 videoFrames = read(getImpl(obj), index);
Why should it run out of memory if the array is completely preallocated and it is only reading one frame at a time?
댓글 수: 1
David Tarkowski
2011년 5월 11일
Can you provide more of your code that is causing the problems. Specifically, how are you using mmreader or aviread?
답변 (1개)
Walter Roberson
2011년 5월 10일
When the entire contents of a structure field are being replaced, MATLAB does not copy the new values in to the existing storage: it unlinks the old storage from that place (returning it to the memory manager if there are no further references to it) and links in the new value array. Thus, even if everything else was going right, it would not be the old memory that was being used. Memory fragmentation permitting, though, any memory returned to the memory manager in this way would be eligible to be allocated within aviread() or mmread() and possibly end up being used in the structure for some later frame.
Now, in this description, notice that I said "returning it to the memory manager if there are no further references to it." You have a problem in that regards: the blocks have many other references to them!
When you assign the same value (the entire structure in this case) to a number of different locations (the array D(1:nFrames)), MATLAB saves on memory and computation by setting each of the destination entries to point to the same value block. Your code generates a single array of 1's, and makes nFrames references to that single array. When it needs to alter an instance that is shared, it unlinks in the destination, reducing the reference count. If you think about that briefly, you will see that your code ends up pre-allocating a small amount of memory, and then to need to allocate more memory for each frame read in.
In short: change your code to
D(1:nFrames) = struct('cdata',[], 'colormap, []);
for K = 1:nFrames
D(K).cdata = zeros(vidHeight,VidWidth,3,'uint8');
end
(Arrays of all zeros can be faster than arrays of all ones.)
If you run out of room in doing this, you would not have had room for all of the frames.
Yeh, this isn't vectorized, but the vectorized versions either end up sharing memory or end up needing temporary memory too large for you to afford.
댓글 수: 2
John
2011년 5월 10일
Walter Roberson
2011년 5월 10일
VideoReader's read function, http://www.mathworks.com/help/techdoc/ref/videoreader.read.html
VideoWriter's writeVideo function, http://www.mathworks.com/help/techdoc/ref/videowriter.writevideo.html
Note: I have not used these functions myself, and so do not know how much internal buffering they need to do.
카테고리
도움말 센터 및 File Exchange에서 Read, Write, and Modify Image에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!