Matlab: Save image frames as YCbCr video

166 views Asked by At

So I have 10 separate image frames of YCbCr format. How can I export it as a YCbCr video in Matlab so that it can be viewed through a supported video player?

Update-1

for Frame_Index = 1: frames
    YCbCr_Movie_Structure_Array(Frame_Index).cdata = uint8(images(Frame_Index));
end

I'm getting the error: Conversion to uint8 from cell is not possible.

1

There are 1 answers

8
MichaelTr7 On BEST ANSWER

Expoting Frames to a Video File

Not sure if you want to keep the frames in the YCbCr colour-space but if that's the case... One method is to save all the individual frames into a structure that has the fields/members 'cdata' and 'colormap'. After looping through the frames and saving them to the structure the structure can be exported to a video file. To export the video to file a video object must first be created using the VideoWriter() function. The entire structure can then be written to the video object and transitively the file by using the WriteVideo() function. It is good to keep in mind to open() and close() the video object before performing any reading and writing from this object similar to how text files are handled. In the example below the video is exported to a .mp4 file. The frame rate and quality can be configured by the dot properties .FrameRate and .Quality respectively.

Method 1: Using a Structure → Video Object (File)

%Creating 10 test images/frames%
Frame_1 = randi(255,[400 400 3]);
Frame_2 = randi(255,[400 400 3]);
Frame_3 = randi(255,[400 400 3]);
Frame_4 = randi(255,[400 400 3]);
Frame_5 = randi(255,[400 400 3]);
Frame_6 = randi(255,[400 400 3]);
Frame_7 = randi(255,[400 400 3]);
Frame_8 = randi(255,[400 400 3]);
Frame_9 = randi(255,[400 400 3]);
Frame_10 = randi(255,[400 400 3]);

Number_Of_Frames = 10;
[Video_Height,Video_Width,Number_Of_Channels] = size(Frame_1);

%Creating a matrix with dimensions of the video with three channels%
Colour_Channel_Matrix = zeros(Video_Height,Video_Width,3,'uint8');

%Creating a video structure to hold all the frames%
YCbCr_Movie_Structure_Array = struct('cdata',Colour_Channel_Matrix, 'colormap', []);

%Scanning the frames into the video structure%
for Frame_Index = 1: Number_Of_Frames
    YCbCr_Movie_Structure_Array(Frame_Index).cdata = uint8(eval("Frame_" + num2str(Frame_Index)));
end

%Creating a video object to save the video structure to%
Video_Object = VideoWriter('Saved_Video.mp4','MPEG-4'); 
Video_Object.FrameRate = 30; 
Video_Object.Quality = 100;
open(Video_Object);

writeVideo(Video_Object,YCbCr_Movie_Structure_Array);
close(Video_Object);

Method 2: Directly Into Video Object (File)

This method is a lot quicker but losses some flexibility in manipulating and checking/validating frame before writing them to a file.

%Creating 10 test images%
Frame_1 = randi(255,[400 400 3]);
Frame_2 = randi(255,[400 400 3]);
Frame_3 = randi(255,[400 400 3]);
Frame_4 = randi(255,[400 400 3]);
Frame_5 = randi(255,[400 400 3]);
Frame_6 = randi(255,[400 400 3]);
Frame_7 = randi(255,[400 400 3]);
Frame_8 = randi(255,[400 400 3]);
Frame_9 = randi(255,[400 400 3]);
Frame_10 = randi(255,[400 400 3]);

Images = {Frame_1,Frame_2,Frame_3,Frame_4,Frame_5,Frame_6,Frame_7,Frame_8,Frame_9,Frame_10};
Number_Of_Frames = length(Images);

%Creating a video object to save the video structure to%
Video_Object = VideoWriter('Saved_Video.mp4','MPEG-4'); 
Video_Object.FrameRate = 30; 
Video_Object.Quality = 100;
open(Video_Object);

%Scanning the frames into the video structure%
for Frame_Index = 1: Number_Of_Frames    
    writeVideo(Video_Object,uint8(cell2mat(Images(Frame_Index))));
end

close(Video_Object);