0

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 Answers1

0

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);
MichaelTr7
  • 4,737
  • 2
  • 6
  • 21
  • Thank you very much for detailed explanation. I have all the frames in images array. Each frame is 352x240x3 uint8. How can I use this images array instead? I added the error I'm getting while trying to use this. Thanks. –  Feb 01 '21 at 17:42
  • Try this `YCbCr_Movie_Structure_Array(Frame_Index).cdata = uint8(cell2mat(images(Frame_Index)));` – MichaelTr7 Feb 01 '21 at 17:47
  • 1
    That did the trick. I'm wondering though, is there any way to do it without using a struct though? –  Feb 01 '21 at 17:52
  • Yes, there is, each frame can be written one by one into the video object, but that method also involves a loop. This method has the benefit that `implay()` can be used on the structure to view the video and also the values of each frame can be viewed in the structure. – MichaelTr7 Feb 01 '21 at 17:57
  • Added the second way to my answer. – MichaelTr7 Feb 01 '21 at 18:02
  • 1
    Thank you so much. –  Feb 01 '21 at 18:07
  • If I want to save the frames I had with .yuv extension, what changes should I make? –  Feb 01 '21 at 19:00
  • 1
    Not too sure about the details about that, but here’s a question going over it: [YUV File Format](https://stackoverflow.com/questions/5194285/yuv-file-format) – MichaelTr7 Feb 01 '21 at 19:02