Search code examples
opencvimage-processingvideo-processingopencv3.0image-compression

How to convert encoded video file to raw video format | OpenCV to read the raw file


It would be appreciated If someone could guide me on:

1 - How do I can convert encoded video file (.mp4) to raw video format.

2 - How do I can read the frames of this raw video file in the OpenCV library?

 eg: To read the .mp4 I can use - 
 cv::VideoCapture cap("abc.mp4");

Thank you in advance.


Solution

  • I am not sure this is very sensible (because of the file size involved), but it does what you ask.

    # Generate sample movie with 250 frames of 640x480 pixels
    ffmpeg -v warning -y -f lavfi -i testsrc=decimals=0:s=640x480:rate=25 -t 10 movie.mov
    

    That looks like this (except this is a GIF with limited colours and framerate because of StackOverflow limitations):

    enter image description here

    # Check number of frames is 250
    ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 movie.mov
    250
    
    # Check size. It is 54kB
    -rw-r--r--     1 mark  staff       54939 14 May 10:02 movie.mov
    
    # Now make into raw BGR24 video
    ffmpeg -v error -i movie.mov -pix_fmt bgr24 -f rawvideo -an -sn movie.bgr24
    
    # Check size. It is now 230400 kB = 640x480 pixels of 3 bytes BGR at 25 fps for 10s
    -rw-r--r--     1 mark  staff   230400000 14 May 10:11 movie.bgr24
    

    Now you can read it in OpenCV without doing any video decompression. C++ is not my forte, but this should work:

    #include <vector>
    #include <iostream>
    #include <opencv2/opencv.hpp>
    
    int
    main(int argc,char*argv[])
    {
       std::ifstream file("movie.bgr24", std::ios::binary);
       unsigned int i=0;
    
       std::vector<unsigned char> buffer(640*480*3);
    
       while(file.read((char *)&buffer[0],640*480*3)){
          i++;
          std::cout << "Frame: " << i << std::endl;
          cv::Mat img(cv::Size(640,480),CV_8UC3,&buffer[0]);
          cv::imshow ("RAW", img);
          cv::waitKey(0);
       }
    }