编程语言: C++(C11标准)

OpenCV: 4.1.1

Platform: Windows / Linux

大致逻辑:

  1. 读取摄像头或者读取视频文件;
  2. 获取视频帧的相关信息:图像尺寸和帧数;
  3. 创建保存视频文件,并设定视频编码格式等信息;
  4. 逐帧读取并处理,然后写入到输出视频文件中;
  5. 关闭摄像头或源视频文件,关闭输出视频文件;

代码如下:

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

int main(int argc, const char ** argv){
	cv::String base_dir = "F:/dump/TEST-ALL/Dataset/EIS/";
	cv::String date_id = "20211013";
	cv::String phone_id = "Prague-WH03-0101";
	cv::String video_id = "easy.mp4";

	cv::String ori_dir = "ori/";
	cv::String cal_dir = "cal/";
	cv::String out_dir = "out/";
	cv::String dump_dir = "dump/";
	cv::String cal_ver = "version7";

        double beg_, end_;
        double freq = cv::getTickFrequency();

        cv::String input_video = base_dir + ori_dir + date_id + "/" + phone_id + "/" + video_id;
	cv::VideoCapture input_stream(input_video);
	ASSERT(input_stream.isOpened(), "video not found: %s", input_video.c_str());
	
	float frame_width = input_stream.get(cv::CAP_PROP_FRAME_WIDTH);
	float frame_height = input_stream.get(cv::CAP_PROP_FRAME_HEIGHT);
	int frame_count = input_stream.get(cv::CAP_PROP_FRAME_COUNT);

	//create a video writer for saving processed frames
	cv::String output_dir = base_dir + out_dir + date_id + "/" + phone_id + "/";
	tcl_depth_video::MakeDir(output_dir);
	cv::String output_video = output_dir + video_id;
	cv::VideoWriter output_stream;
	int fps = 30;
	int fourcc = cv::VideoWriter::fourcc('m', 'p', '4', 'v');
	cv::Size frame_size(frame_width, frame_height);
	output_stream.open(output_video, fourcc, fps, frame_size, true);
	ASSERT(output_stream.isOpened(), "video cannot be created: %s", output_video.c_str());
	
        // create a global uid for synchronize log/dump information
        char uid[16];
	// output frame
	cv::Mat input_frame(cv::Size(frame_width, frame_height), CV_8UC3);
	cv::Mat output_frame(cv::Size(frame_width, frame_height), CV_8UC3);

        for (int i=0; i<frame_count; ++i) {
		memset(uid, 0, sizeof(uid));
		sprintf_s(uid, "%08d", i);
                VIDEO_DEPTH_LOGI("filename: %s", uid);
		ASSERT(input_stream.read(input_frame), "video broken or incomplete!");
		ASSERT(input_frame.size().width == frame_width, "width mismatch");
		ASSERT(input_frame.size().height == frame_height, "width mismatch");
		ASSERT(input_frame.channels() == 3, "unexpected channel number of frame");
		beg_ = cv::getTickCount();
		// here's your code
		// a demo one is to convert color into HSV
		cv::cvtColor(input_frame, output_frame, cv::COLOR_BGR2HSV);
                end_ = cv::getTickCount();
                VIDEO_DEPTH_LOGI("frame %d cost: %.4f ms.", i, (1000 * (end_ - beg_) / freq));
		// save this frame to the output video stream
		output_stream.write(output_frame);
        }

	input_stream.release();
	output_stream.release();

	PAUSE();
	return 0;
}

完毕。