Creating MJEPG video from multiple JPEG encoded images without using cv::imdecode()

Anh Tú Nguyễn

I need to store multiple encoded frames in memory.
I am using cv::imencode(".jpg", ...) for compressing and storing the encoded images to std::list<std::vector<u_char>> compressed_images - a list of compressed images.

I want to create a video from compressed_images, but I must use cv::imdecode() to decode all the images to cv::Mat, then use cv::VideoWriter to save the images to MJPEG video.

Can I skip cv::imdecode(), or use other solution for avoid encoding two times?

Rotem

You may PIPE the encoded images to FFmpeg.

According to the following post, you can "simply mux the JEPG images to make a video".

In case the frames are in memory, you can write the encoded images to an input PIPE of FFmpeg.

Instead of -f image2, use -f image2pipe format flag.

Implementing the solution in C++ is too difficult for me.
I have implemented a Python code sample.

The code sample:

  • Builds a list of 100 encoded frames (green frame counter).
  • PIPE the encoded frames to ffmpeg sub-process.
    The encoded images are written to stdin input stream of the sub-process.

Here is the Python code sample:

import numpy as np
import cv2
import subprocess as sp

# Generate 100 synthetic JPEG encoded images in memory:
###############################################################################
# List of JPEG encoded frames.
jpeg_frames = []

width, height, n_frames = 640, 480, 100  # 100 frames, resolution 640x480

for i in range(n_frames):
    img = np.full((height, width, 3), 60, np.uint8)
    cv2.putText(img, str(i+1), (width//2-100*len(str(i+1)), height//2+100), cv2.FONT_HERSHEY_DUPLEX, 10, (30, 255, 30), 20)  # Green number

    # JPEG Encode img into jpeg_img
    _, jpeg_img = cv2.imencode('.JPEG', img)

    # Append encoded image to list.
    jpeg_frames.append(jpeg_img)
###############################################################################

#FFmpeg input PIPE: JPEG encoded images
#FFmpeg output AVI file encoded with MJPEG codec.
# https://video.stackexchange.com/questions/7903/how-to-losslessly-encode-a-jpg-image-sequence-to-a-video-in-ffmpeg
process = sp.Popen('ffmpeg -y -f image2pipe -r 10 -i pipe: -codec copy out.avi', stdin=sp.PIPE)

# Iterate list of encoded frames and write the encoded frames to process.stdin
for jpeg_img in jpeg_frames:
    process.stdin.write(jpeg_img)

# Close and flush stdin
process.stdin.close()

# Wait one more second and terminate the sub-process
try:
    process.wait(1)
except (sp.TimeoutExpired):
    process.kill()

Update: C++ implementation:

#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"

#ifdef _MSC_VER
#include <Windows.h>    //For Sleep(1000)
#endif

#include <stdio.h>

int main()
{
    int width = 640;
    int height = 480;
    int n_frames = 100;

    //Generate 100 synthetic JPEG encoded images in memory:
    //////////////////////////////////////////////////////////////////////////
    std::list<std::vector<uchar>> jpeg_frames;

    for (int i = 0; i < n_frames; i++)
    {
        cv::Mat img = cv::Mat(height, width, CV_8UC3);
        img = cv::Scalar(60, 60, 60);

        cv::putText(img, std::to_string(i + 1), cv::Point(width / 2 - 100 * (int)(std::to_string(i + 1).length()), height / 2 + 100), cv::FONT_HERSHEY_DUPLEX, 10, cv::Scalar(30, 255, 30), 20);  // Green number

        //cv::imshow("img", img);cv::waitKey(1);

        std::vector<uchar> jpeg_img;

        cv::imencode(".JPEG", img, jpeg_img);

        jpeg_frames.push_back(jpeg_img);
    }
    //////////////////////////////////////////////////////////////////////////

    //In Windows (using Visual Studio) we need to use _popen and in Linux popen
#ifdef _MSC_VER
    //ffmpeg.exe must be in the system path (or in the working directory)
    FILE *pipeout = _popen("ffmpeg -y -f image2pipe -r 10 -i pipe: -codec copy out.avi", "wb"); //For Windows use "wb"
#else
    //https://batchloaf.wordpress.com/2017/02/12/a-simple-way-to-read-and-write-audio-and-video-files-in-c-using-ffmpeg-part-2-video/
    FILE *pipeout = popen("ffmpeg -y -f image2pipe -r 10 -i pipe: -codec copy out.avi", "w"); //For Linux use "w"

    //In case ffmpeg is not in the execution path, you may use full path:
    //popen("/usr/bin/ffmpeg -y -f image2pipe -r 10 -i pipe: -codec copy out.avi", "w");
#endif

    std::list<std::vector<uchar>>::iterator it;

    //Iterate list of encoded frames and write the encoded frames to pipeout
    for (it = jpeg_frames.begin(); it != jpeg_frames.end(); ++it) 
    {
        std::vector<uchar> jpeg_img = *it;

        // Write this frame to the output pipe
        fwrite(jpeg_img.data(), 1, jpeg_img.size(), pipeout);
    }

    // Flush and close input and output pipes
    fflush(pipeout);

#ifdef _MSC_VER
    _pclose(pipeout);
#else
    pclose(pipeout);
#endif

    //It looks like we need to wait one more second at the end.
    Sleep(1000);

    return 0;
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Java

Python creating video from images using opencv

From Dev

ffmpeg split JPEG-encoded MOV video into frames without reencoding

From Dev

cv2.imdecode() returns None from image in base64, mimetype image/jpeg received via Websockets

From Dev

Creating an MJPEG video from still images using C#

From Dev

How to extract images from video files using FFmpeg without blur?

From Dev

Get back a numpy array from JPEG encoded (by cv2.imencode) bytearray

From Dev

creating video from sequence of images javacv

From Dev

Creating video from images with different SARs with FFMPEG

From Dev

Creating a video from a sequence of images in Matlab

From Dev

Creating a video from set of images Android

From Dev

Generate gif from jpeg images using ffmpeg

From Dev

Creating multiple images using multiple URLs

From Dev

Making a loop with script using cv2 that converts video to images

From Dev

FFMpeg convert jpeg images to video

From Dev

Add watermark to each frame while creating video from images using ffmpeg

From Dev

creating video from selected images using FFMPEG through command Line Android

From Dev

Creating Video Slideshow From Images With Different Sizing/Aspect Ratio Using FFMPEG?

From Dev

Multiple backgrounds without using images

From Dev

How to display multiple jpeg images in a table using python?

From Dev

FFMpeg : Converting a video file to a gif with multiple images from video

From Dev

ffmpeg slideshow video from images creating empty mp4

From Dev

Create MP4 video from multiple images + musics using FFMPEG command

From Dev

create video from jpg images using ffmpeg

From Dev

lossless video using FFmpeg ffv1 on jpeg images is not compressed but expanded

From Dev

Display multiple images without using <img> tag?

From Dev

How to display images from cv2 in browser using flask?

From Dev

Extract tree count from images-using CV

From Java

Creating Thumbnail from video on S3 without downloading

From Dev

Using local images without creating a local registry in kubernetes

Related Related

  1. 1

    Python creating video from images using opencv

  2. 2

    ffmpeg split JPEG-encoded MOV video into frames without reencoding

  3. 3

    cv2.imdecode() returns None from image in base64, mimetype image/jpeg received via Websockets

  4. 4

    Creating an MJPEG video from still images using C#

  5. 5

    How to extract images from video files using FFmpeg without blur?

  6. 6

    Get back a numpy array from JPEG encoded (by cv2.imencode) bytearray

  7. 7

    creating video from sequence of images javacv

  8. 8

    Creating video from images with different SARs with FFMPEG

  9. 9

    Creating a video from a sequence of images in Matlab

  10. 10

    Creating a video from set of images Android

  11. 11

    Generate gif from jpeg images using ffmpeg

  12. 12

    Creating multiple images using multiple URLs

  13. 13

    Making a loop with script using cv2 that converts video to images

  14. 14

    FFMpeg convert jpeg images to video

  15. 15

    Add watermark to each frame while creating video from images using ffmpeg

  16. 16

    creating video from selected images using FFMPEG through command Line Android

  17. 17

    Creating Video Slideshow From Images With Different Sizing/Aspect Ratio Using FFMPEG?

  18. 18

    Multiple backgrounds without using images

  19. 19

    How to display multiple jpeg images in a table using python?

  20. 20

    FFMpeg : Converting a video file to a gif with multiple images from video

  21. 21

    ffmpeg slideshow video from images creating empty mp4

  22. 22

    Create MP4 video from multiple images + musics using FFMPEG command

  23. 23

    create video from jpg images using ffmpeg

  24. 24

    lossless video using FFmpeg ffv1 on jpeg images is not compressed but expanded

  25. 25

    Display multiple images without using <img> tag?

  26. 26

    How to display images from cv2 in browser using flask?

  27. 27

    Extract tree count from images-using CV

  28. 28

    Creating Thumbnail from video on S3 without downloading

  29. 29

    Using local images without creating a local registry in kubernetes

HotTag

Archive