在许多应用程序中,我们希望将流输出到视频流,而OpenCV提供了相关的对象cv::VideoWriter
。我们可以将每一帧流传输到cv::VideoWriter
对象,最后调用其cv::VideoWriter.release()
方法。下面的程序展示了一个对输入视频做对数极坐标变换的例子。
#include <opencv2/opencv.hpp>
#include <iostream>
int main(int argc, char const *argv[])
{
cv::namedWindow("example", cv::WINDOW_AUTOSIZE);
cv::namedWindow("log_polar", cv::WINDOW_AUTOSIZE);
cv::VideoCapture capture(argv[1]);
double fps = capture.get(cv::CAP_PROP_FPS);
cv::Size size{
(int)capture.get(cv::CAP_PROP_FRAME_WIDTH),
(int)capture.get(CV_CAP_PROP_FRAME_HEIGHT)};
cv::VideoWriter writer;
writer.open(argv[2], CV_FOURCC('M', 'J', 'P', 'G'), fps, size);
cv::Mat logpolar_frame, bgr_frame;
while (true)
{
capture >> bgr_frame;
if (bgr_frame.empty())
{
break;
}
cv::imshow("example", bgr_frame);
cv::logPolar(
bgr_frame,
logpolar_frame,
cv::Point2f(
bgr_frame.cols / 2,
bgr_frame.rows / 2
),
40,
cv::WARP_FILL_OUTLIERS
);
cv::imshow("log_polar", logpolar_frame);
writer << logpolar_frame;
char c = cv::waitKey(10);
if (c == 27)
break;
}
capture.release();
return 0;
}
我们打开一个视频并读取打开cv::VideoWriter
对象的文件所需的一些属性(每秒帧数、图像宽度和高度)。然后,我们从cv::VideoWriter
对象逐帧读取视频,将帧转换为对数极坐标格式,并将对数极坐标帧一次一个写入到这个新视频文件中,直到没有剩余的帧或直到用户通过按Esc退出。
对cv::VideoWriter
对象的调用包含几个我们应该理解的参数。第一个是新文件的文件名。第二个是视频编解码器,将使用该视频编解码器对视频流进行压缩。市面上有很多这样的编解码器,但你选择的编解码器必须在你的机器上可用(编解码器与OpenCV是分开安装的)。在我们的示例中,我们选择了相对流行的MJPG编解码器;我们使用宏CV_FOURCC()
将此选择指示给OpenCV,该宏接受四个字符作为参数。这些字符构成了编解码器的“四字符码”,每个编解码器都有这样的码。motion jpeg的四个字符代码是“MJPG”,因此我们将其指定为CV_FOURCC('M','J','P','G')
。接下来的两个参数是重放帧速率和我们将使用的图像的大小。在我们的示例中,我们将这些值设置为从原始视频中获得的值。