利用opencv或gstreamer将大量的图片转换成视频或者视频流媒体

 

仅用opencv的方式:

// main2.cpp

#include "opencv2/opencv.hpp"
#include <opencv2/videoio.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(){
    Mat image;
    Mat image2;

    VideoWriter writer;
    int codec = VideoWriter::fourcc('M', 'P', '4', 'V');
    double fps = 15.0;
    string filename = "live.mp4";
    Size sizeFrame(1280,960);
    writer.open(filename, codec, fps, sizeFrame);

    image = cv::imread("test.jpg", 1);
    resize(image, image, sizeFrame);
    image2 = cv::imread("test2.jpg", 1);
    resize(image2, image2, sizeFrame);
    for (int i = 0 ; i < 200 ; i ++) {
        if (i%10 == 0)
            writer.write(image);
        else
            writer.write(image2);
    }

    writer.release();
    return 0;
}

 

使用opencv的VideoWriter作为opencv的mat的输入接口,将mat表示的图片转发给gstreamer处理:

// main.cpp

#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>

using namespace std;

int main()
{
    cv::VideoWriter writer;
    writer.open("appsrc ! videoconvert ! x264enc noise-reduction=10000 tune=zerolatency threads=4 ! matroskamux ! filesink location=test.mp4 sync=false", 0, (double)15, cv::Size(640, 480), true);
    if (!writer.isOpened()) {
        printf("=ERR= can't create video writer\n");
        return -1;
    }

    cv::Mat image, image2;
    int key;

    image = cv::imread("test.jpg", 1);
    resize(image, image, cv::Size(640, 480));
    image2 = cv::imread("test2.jpg", 1);
    resize(image2, image2, cv::Size(640, 480));

    for (int i = 0 ; i < 200 ; i ++) {
        if (i%10 == 0)
            writer.write(image);
        else
            writer.write(image2);
    }

    writer.release();
    return 0;
}

 

编译脚本很简单:

# CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(gstreamer-appsrc LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(OpenCV REQUIRED)

INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})

add_executable(gstreamer-appsrc main.cpp)

target_link_libraries(gstreamer-appsrc ${OpenCV_LIBS})

 

另外,对于opencv中的fourcc的解释可在videoio.hpp的800多行找到注释,注释如下:

/** @overload
    @param filename Name of the output video file.
    @param fourcc 4-character code of codec used to compress the frames. For example,
    VideoWriter::fourcc('P','I','M','1') is a MPEG-1 codec, VideoWriter::fourcc('M','J','P','G') is a
    motion-jpeg codec etc. List of codes can be obtained at [Video Codecs by
    FOURCC](http://www.fourcc.org/codecs.php) page. FFMPEG backend with MP4 container natively uses
    other values as fourcc code: see [ObjectType](http://www.mp4ra.org/codecs.html),
    so you may receive a warning message from OpenCV about fourcc code conversion.
    @param fps Framerate of the created video stream.
    @param frameSize Size of the video frames.
    @param isColor If it is not zero, the encoder will expect and encode color frames, otherwise it
    will work with grayscale frames.

    @b Tips:
    - With some backends `fourcc=-1` pops up the codec selection dialog from the system.
    - To save image sequence use a proper filename (eg. `img_%02d.jpg`) and `fourcc=0`
      OR `fps=0`. Use uncompressed image format (eg. `img_%02d.BMP`) to save raw frames.
    - Most codecs are lossy. If you want lossless video file you need to use a lossless codecs
      (eg. FFMPEG FFV1, Huffman HFYU, Lagarith LAGS, etc...)
    - If FFMPEG is enabled, using `codec=0; fps=0;` you can create an uncompressed (raw) video file.
    */
    CV_WRAP VideoWriter(const String& filename, int fourcc, double fps,
                Size frameSize, bool isColor = true);

大意是,对于某些视频处理后端,如果fource=-1则会弹出选择框让你选择保存格式(某些后端不会弹出,这时相当于fourcc=0);如果想使用文件名的后缀来指定格式,则设置fourcc=0或者fps=0,但是我们一般情况下指定fourcc=0,而fps指定自己想要的值,这样比较好。

本文的方法就是这样的,当设置fourcc=0时,VideoWriter看到 "appsrc ! videoconvert ! x264enc noise-reduction=10000 ..." 之后,就知道格式为 gstreamer 接口。

 

posted @ 2021-01-26 15:40  微信公众号--共鸣圈  阅读(1783)  评论(1编辑  收藏  举报