opencv+vs2015:实现同一窗口的左右部分,差帧播放视频一个视频,实现VR效果

 
//把两个视频合成一个视频,播放合成之后的视频,效果就是同一个窗口的左右两边同时播放两个视频
//  successfully !!

#include"stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;


// 获取视频 capture 的第 pos 帧的图片
IplImage* getFrameFromVideo(CvCapture* capture, int pos)
{
	IplImage *frame = NULL;
	cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, pos);
	printf("pos: %d \t",pos);
	//获取一帧图片
	frame = cvQueryFrame(capture);   
	
	if (!frame) return NULL; 
	else return frame;
}


//把两个视频合成一个视频
void combine_two_videos_into_one()
{
	IplImage *newFrame = NULL;
	IplImage *frame1 = NULL;
	IplImage *frame2 = NULL;

	// 用cvCaptureFromAVI()跟cvCaptureFromFile()、cvCreateFileCapture()都是一样的作用
	CvCapture * pCapture1 = cvCaptureFromAVI(".\\video1.avi");  //输入第一个视频地址
	CvCapture * pCapture2 = cvCaptureFromAVI(".\\video2.avi");  //输入第二个视频地址
	CvRect rect;
	CvVideoWriter *pWriter = NULL;

	//  cvGetCaptureProperty(Capture* cap,int property_index)获取视频文件的一些属性
	//  获取视频的帧总数目
	int frameNo1 = (int)cvGetCaptureProperty(pCapture1, CV_CAP_PROP_FRAME_COUNT);
	int frameNo2 = (int)cvGetCaptureProperty(pCapture2, CV_CAP_PROP_FRAME_COUNT);
	if (frameNo1 != frameNo2)
		printf("video length 1 != video length 2\n");
	else
		printf("Total frame numbers: %d\n", frameNo1);
	//  获取帧宽
	int frameWidth1 = (int)cvGetCaptureProperty(pCapture1, CV_CAP_PROP_FRAME_WIDTH);
	int frameWidth2 = (int)cvGetCaptureProperty(pCapture2, CV_CAP_PROP_FRAME_WIDTH);
	if (frameWidth1 != frameWidth2)
		printf("video width 1 != video width 2\n");
	else
		printf("frame width: %d\n", frameWidth1);
	//  获取帧高
	int frameHeight1 = (int)cvGetCaptureProperty(pCapture1, CV_CAP_PROP_FRAME_HEIGHT);
	int frameHeight2 = (int)cvGetCaptureProperty(pCapture2, CV_CAP_PROP_FRAME_HEIGHT);
	if (frameHeight1 != frameHeight2)
		printf("video height 1 != video height 2\n");
	else
		printf("frame height: %d\n", frameHeight1);
	//  获取帧率
	int fps1 = (int)cvGetCaptureProperty(pCapture1, CV_CAP_PROP_FPS);
	int fps2 = (int)cvGetCaptureProperty(pCapture2, CV_CAP_PROP_FPS);
	if (fps1 != fps2)
		printf("video fps 1 != video fps 2\n");
	else
		printf("frame fps: %d\n", fps1);


	int initFlag = 0;
	int counter = 0;
	/* 
	    在VR系统中,双目立体视觉起了很大作用。用户的两只眼睛看到的不同图像是分别产生的,显示在不同的显示器上。
	    有的系统采用单个显示器,但用户带上特殊的眼镜后,	一只眼睛只能看到奇数帧图像,另一只眼睛只能看到偶数帧图像,
		奇、偶帧之间的不同也就是视差就产生了立体感。
	*/
	// 可以通过控制 counter 的值,让视频差帧播放、快进播放
	while ((frame1 = getFrameFromVideo(pCapture1,3*counter)) != NULL && (frame2 = getFrameFromVideo(pCapture2,3*counter+1)) != NULL)
	{
		printf("counter : %d\n", counter++);
		if (initFlag == 0)
		{
			//IplImage* cvCreateImage(CvSize size, int depth, int channels)
			newFrame = cvCreateImage(cvSize(frame1->width * 2, frame1->height), frame1->depth, frame1->nChannels);			
			// 输入存放合成后的视频的地址
			pWriter = cvCreateVideoWriter(".\\videoCombine.avi", CV_FOURCC('X', 'V', 'I', 'D'), fps1, cvSize(frame1->width * 2, frame1->height), 1);
			initFlag = 1;
		}
		rect.x = 0;
		rect.y = 0;
		rect.height = frameHeight1;
		rect.width = frameWidth1;
		//利用ROI实现视频拼接
		cvSetImageROI(newFrame, rect);
		cvCopy(frame1, newFrame);
		cvResetImageROI(newFrame);

		rect.x = frameWidth1;
		rect.y = 0;
		rect.height = frameHeight1;
		rect.width = frameWidth1;
		cvSetImageROI(newFrame, rect);
		//cvCopyImage(frame2, newFrame);
		/*
		如果设定了ROI等参数的时候,cvCopy只是复制被设定的区域,复制到一个和所设定参数相吻合的新的IplImage中
		cvCopy的原型是:
		void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );
		在使用这个函数之前,你必须用cvCreateImage()一类的函数先开一段内存,然后传递给dst。cvCopy会把src中的数据复制到dst的内存中。
		*/
		cvCopy(frame2, newFrame);
		cvResetImageROI(newFrame);
		cvWriteFrame(pWriter, newFrame);

		cvShowImage("合成的视频", newFrame);
		char c = cvWaitKey(33);
		if (c == 27) break;
	}
	cvReleaseImage(&frame1);
	cvReleaseImage(&frame2);
	cvReleaseImage(&newFrame);
	cvReleaseVideoWriter(&pWriter);
}


int main(int argc, char *argv[])
{
	combine_two_videos_into_one();    
	return 0;
}

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值