首页 > 代码库 > 使用opencv进行多路视频的播放

使用opencv进行多路视频的播放

在监控领域,我们时常需要对多路视频进行实时的播放,这到底是怎么实现的呢?使用opencv的朋友可能会想:我可以先定义一个VideoCapture的数组,然后在一个for循环中,逐一读取各路视频并显示,但是这显然不是同步的,设想一下,如果有32路视频需要同时播放,而一般摄像机的帧率为25fps或30fps,那么按上述方法进行播放,第一路与第三十二路视频的延迟会有1秒多,如果我们需要在其间做一些图像处理,那么延迟将会更大。

有过多线程编程或多核编程经验的朋友会觉得这个问题很好解决,这就是一个简单的并行问题。本章节提供使用openMP多核编程的方法实现多路视频的播放:

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "omp.h"

using namespace cv;
using namespace std;

#define CAM_NUM 4

int _tmain(int argc, _TCHAR* argv[])
{

	VideoCapture cap[CAM_NUM];
	Mat img;
	string str = "scene_1//frame_%4d.jpg";
	int i;

	#pragma omp parallel for private(str)
	for (i=0;i<CAM_NUM;i++)
	{
		cap[i].open(str);
	}

	int width = cap[0].get(CV_CAP_PROP_FRAME_WIDTH);
	int height = cap[0].get(CV_CAP_PROP_FRAME_HEIGHT);
	int min_width = width/2;
	int min_height = height/2;

	Mat imageShow(height,width,CV_8UC3);
	int left,top;
	Mat temp;
	bool runflag = true;

	while (1)
	{
		#pragma omp parallel for private(img,temp, left, top)
		for (i=0;i<CAM_NUM;i++)
		{
			cap[i] >> img;
			if (img.empty())
			{
				runflag = false;
				break;
			}
			resize(img,temp,Size(min_width,min_height));
			left = i/2 *min_width;
			top = i%2 *min_height;
			temp.copyTo(imageShow(Rect(left,top,min_width,min_height)));
		}

		if (!runflag)
		{
			break;
		}
		namedWindow("Image");
		imshow("Image", imageShow);
		waitKey(33);
	}
	return 0;
}

一张截图如下:


是不是很有意思!你可以尝试修改一下视频通道的数量,如果仅是播放,一个核播放4路视频完全没有问题,一个四核的计算机可以尝试16路视频的同步播放。

本文中使用了多核编程的思想,因为现在多核计算机很普遍了,这也必将是以后的趋势,想更多的了解openMP与opencv的结合请继续关注本人博客!!会有大波新内容介绍给大家的!

使用opencv进行多路视频的播放