OpenCV合成视频

OpenCV合成视频

主要用到VideoCapture, VideoWriter

/*
 * Demo制作,将原始视频与该视频跟踪轨迹合并为一个视频。
 * 用法:s键将将改合成帧加入到输出视频中
 */


#include <iostream>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;


int main()
{
    const string originalFramePath = "/home/corfox/Data/GOPR/7";        // 原始视频帧路径
    string originalFrameName;                                           // 原始视频帧图像名
    ostringstream numToStr;
    Mat originalFrame;                                                  // 原始视频帧图像
    const int originalFrameNums = 1456;                                 // 原始视频帧数目
    int originalFrameWidth = 960;
    int originalFrameHeight = 540;

    const string mapVideo = "/home/corfox/Videos/7_25.mp4";             // 轨迹与地图视频
    VideoCapture videoCapture;
    Mat mapFrame;

    videoCapture.open(mapVideo);
    if (!videoCapture.isOpened())
        return 1;
    int mapFrameWidth = videoCapture.get(CV_CAP_PROP_FRAME_WIDTH);
    int mapFrameHeight = videoCapture.get(CV_CAP_PROP_FRAME_HEIGHT);

    const string mergeVideo = "/home/corfox/Videos/gopr7_25.avi";       // 合并后的视频
    VideoWriter videoWriter;
    videoWriter.open(mergeVideo, CV_FOURCC('M', 'J', 'P', 'G'), 25, Size(mapFrameWidth + originalFrameWidth, mapFrameHeight + originalFrameHeight));
    Mat mergeFrame;
    Rect roiLeft(0, 0, mapFrameWidth, mapFrameHeight);
    Rect roiRight(mapFrameWidth - 100, mapFrameHeight - 100, originalFrameWidth, originalFrameHeight);
    if (!videoWriter.isOpened())
        return 1;

    int key = -1;
    int numCount = 1;
    while (1)
    {


        if (numCount < 10)
        {
            numToStr << originalFramePath << "/" << "frame0000" << numCount << ".jpg";
            originalFrameName = numToStr.str();
        }
        else if (numCount < 100)
        {
            numToStr << originalFramePath << "/" << "frame000" << numCount << ".jpg";
            originalFrameName = numToStr.str();
        }
        else if (numCount < 1000)
        {
            numToStr << originalFramePath << "/" << "frame00" << numCount << ".jpg";
            originalFrameName = numToStr.str();
        }
        else if (numCount < 10000)
        {
            numToStr << originalFramePath << "/" << "frame0" << numCount << ".jpg";
            originalFrameName = numToStr.str();
        }

        originalFrame = imread(originalFrameName, CV_LOAD_IMAGE_COLOR);
        originalFrameName.clear();
        numToStr.str("");
        numCount++;

        if (numCount > originalFrameNums)
        {
            break;
        }


        if (!videoCapture.read(mapFrame))
        {
            break;
        }

        if (key == 115 || key == 83) // 's' or 'S'
        {
            mergeFrame = Mat(originalFrame.rows + mapFrame.rows, originalFrame.cols + mapFrame.cols, CV_8UC3, Scalar(255, 255, 255));
            mapFrame.copyTo(mergeFrame(roiLeft));
            originalFrame.copyTo(mergeFrame(roiRight));
            videoWriter.write(mergeFrame);

            imshow("merge", mergeFrame);
            mergeFrame.release();
        }

        imshow("map", mapFrame);
        imshow("original", originalFrame);
        key = waitKey(0);
        if (key == 27)
            break;
    }

    videoCapture.release();
    videoWriter.release();
    mapFrame.release();
    originalFrame.release();


    return 0;
}
原文地址:https://www.cnblogs.com/corfox/p/5414988.html