利用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 接口。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM