Writing video in a parfor fails

3 次查看(过去 30 天)
Dear all,
I try to add a circle to each frame of a video. I do this in a PARFOR loop. The only problem is, that the loop fails if I do not call open(VidWriter) inside the loop. With my fairly limited knowledge of PARFOR, I suspect, that the VidWriter is separately initialized for each worker, which then causes the loop to fail, since only one of the workers has an initialized copy of the VidWriter. Is this correct, or is there some other problem. If it is correct, is there a better solution than calling OPEN in every loop iteration? Grateful about any suggestions!
Below a minimal working example (at least on Linux). close all; clear all;
Pool = gcp();
%Load video.
VideoObj = VideoReader('xylophone.mp4');
nFrames = VideoObj.NumberOfFrames;
%Init writer & shape inserter
VideoWriterObj = VideoWriter('xylophone_overlay.mp4','Motion JPEG AVI');
VideoWriterObj.FrameRate = VideoObj.FrameRate;
ShapeInserterObj = vision.ShapeInserter('Shape','Circles');
open(VideoWriterObj);
parfor i = 1:nFrames-1
FrameFull = read(VideoObj, i);
%Insert circle with some random jitter for demo purposes.
FrameFull = step(ShapeInserterObj,FrameFull,...
uint32([50*(1+rand()) 50*(1+rand()) 10]));
%If this OPEN call is no there, PARFOR will fail.
% open(VideoWriterObj);
writeVideo(VideoWriterObj,FrameFull);
end
close(VideoWriterObj);
delete(Pool);

采纳的回答

Edric Ellis
Edric Ellis 2015-3-23
Firstly, when the VideoWriter object is passed to the workers, each worker gets a separate copy of that object (as if it has been saved to disk and then loaded again). I suspect that's why each worker needs to call the open method to ensure the object is ready for writing. In any case, I'm not sure this is really what you want - in your code as written, each worker is writing to the same output file at the same time, this is not likely to succeed terribly well - even if it worked, you'd be relying on the order of execution, which is not sequential for a PARFOR loop.
I'm not sure what your best option is here - it rather depends on how large the data is compared to how long it takes to process. You might need to save intermediate results somewhere, or else return the frames from the loop.

更多回答(1 个)

Dima Lisin
Dima Lisin 2015-3-23
If you call open(...) once before the loop, then you would be trying to have multiple MATLAB workers write frames into the same video file, which is a bad idea.
If you open the video file in every loop iteration, then you also have a problem: the frames may be written out of order.
In summary, parallelizing at the level of video frames is not a good idea in this case. Do you have to process multiple videos? You would be better off having each worker process a different video file.
  2 个评论
David J. Mack
David J. Mack 2015-3-23
That's what I feared. So I will proceed in serial. Thanks, for the answer!
Dima Lisin
Dima Lisin 2015-3-23
You can try splitting up the problem differently:
  1. Use a serial loop to read n frames into memory, where n is reasonably large
  2. Use a parfor to insert the circles into the frames
  3. Use another serial loop to write the frames out into a video file
  4. Repeat until end of the input video file

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 MATLAB Support Package for IP Cameras 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by