Create a video from a 4D array

Hello, I have a problem in this code.
function [] = writeBufferToFinalVideo(buffer)
video = VideoWriter('example','MPEG-4');
video.FrameRate = 25;
open(video)
for i = 1:size(buffer,4)
img = buffer(i);
img(img>1) = 1;
img(img<0) = 0;
writeVideo(video,img);
end
close(video);
end
My buffer is a 4-dimensional array that has frames inside. It is composed of: (height, width, numChannels, framesPerSymbol). The latter is the number of frames that are in a symbol, that is, the size of my buffer.
In my opinion, I think the code is correct, but I always get an empty video without the frames in my buffer.

2 Comments

What is the class if buffer?
class(buffer)
Alber
Alber on 17 Apr 2020
Edited: Alber on 17 Apr 2020
I made the buffer with an array buffer = zeros(height, width, numChannels, framesPerSymbol) and with other function I put the frames of the original video input the buffer.

Sign in to comment.

 Accepted Answer

If buffer is a 4D-array, then you will need to index it like this
img = buffer(:,:,:,i);

9 Comments

Still not working, I'm running it here in case it's of any use to you, maybe the loops are wrong
while hasFrame(videoObject)
frame = double(readFrame(videoObject));
% We update the framesInBuffer counter
framesInBuffer = framesInBuffer + 1;
frameBuffer = double(shiftBuffer(frameBuffer,frame,framesInBuffer));
if framesInBuffer > framesPerSymbol
framesInBuffer = framesPerSymbol;
bypassEncoding = false;
else
bypassEncoding = true;
end
if ~bypassEncoding
if canWeEncode(frameBuffer,alpha,threshold) % True condition
encodedBuffer = steganographicEncoding(frameBuffer,width,height,codeRows,codeCols);
writeBufferToFinalVideo(encodedBuffer);
else % False condition
writeFrameToFinalVideo(squeeze(frameBuffer(:,:,:,1)));
end
end
end
Can you show the output of
size(encodedBuffer)
Also can you see what is the size of buffer(:,:,:,i) inside the function by using a breakpoint.
if I put a break after the line writeBufferToFinalVideo(encodedBuffer), I can generate a video but, only white frames
Ok. It is a bit clear now. Can you show the output of
class(encodedBuffer)
and also show the output of
max(encodedBuffer, [], 'all');
the output of
class(encodedBuffer)
is 'single' and the output of
max(encodedBuffer, [], 'all')
is 236
Alberto, try your code after changing the line to
frameBuffer = double(shiftBuffer(frameBuffer,frame,framesInBuffer))/255;
Yes!!! This is the solution, Thank you!!
I am glad to be of help.
Reason: if the datatype of the matrix is double, MATLAB considers the RGB color values between 0 and 1. Whereas, for your matrix, the values were given in an 8-bit format from 0 to 255. MATLAB takes all value over one as white (that is why you saw white video frames) Dividing by 255, normalizes the value between 0 and 1. I guess, the following will also work for your original code
writeBufferToFinalVideo(uint8(encodedBuffer));

Sign in to comment.

More Answers (1)

Make sure buffer is uint8.
buffer = zeros(height, width, numChannels, framesPerSymbol, 'uint8')

Asked:

on 17 Apr 2020

Commented:

on 18 Apr 2020

Community Treasure Hunt

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

Start Hunting!