opencv3.0+visualstudio2013,使用摄像头录制视频,保存视频,空格键控制开始录制,暂停录制,esc控制结束录制及视频中两种画线方式

opencv3.0提供了专门的摄像头的VideoCapture类,使用时直接实例化即可。

VideoCapture cap;

cap可以用来打开已有的视频文件,也可以用来打开摄像头录制视频。

cap.open(filename);//filename 是已有视频文件的路径
cap.open(0);//0是调用的摄像头的编号

opencv3.0 提供了专用的保存视频的类VideoWriter,使用时直接实例化即可。

VideoWriter writer;
writer.open(filename,CV_FOURCC('P','I','M','1'),30.0.Size(640,480));
//filename是视频文件的完整路径"XX//xx//xxx.avi",CV_FOURCC('P','I','M','1')是视频的编码方式,30.0是视频的帧率,Size(640,480)是每一帧图像的大小

视频的帧率和每一帧图像的大小,也可以直接通过以下方式获取

VideoCapture cap;
cap.open(filename);
double rate = cap.get(CV_CAP_PROP_FPS);//获取帧率
cap.get(CV_CAP_PROP_FRAME_HEIGHT);//获取视频高度
cap.get(CV_CAP_PROP_FRAME_WIDTH);//获取宽度

定义鼠标事件----画直线

bool got_line = false; 
//全局变量 
Point beginPoint = Point(0, 0);//初始化的(0,0) 

bool got_beigin_point = false; 

Point endPoint = Point(0, 0);//初始化(0,0) 

void mouseLineHandler(int event, int x, int y, int flags, void *param) 
{ 
	switch (event) 
	{ 
		case CV_EVENT_LBUTTONDOWN: 
 
			beginPoint = Point(x, y); 
 
			endPoint = beginPoint; 
 
			got_beigin_point = true; 

			break; 
 
		case CV_EVENT_MOUSEMOVE: 
 
			if (got_beigin_point) 

			{ 
		     	endPoint = Point(x, y); 
			} 

			break; 

		case CV_EVENT_LBUTTONUP: 

			got_line = true; 

			endPoint = Point(x, y); 

			got_beigin_point = false; 
 
			break; 
 
		default: 
 
			break; 

	} 


 
} 

定义鼠标回调事件,与窗口绑定

namedWindow("Video", 1); 

	setMouseCallback("Video", mouseLineHandler, NULL);//定义鼠标回调事件

本程序使用_kbhit()获取键盘按键是否被按下,使用_getch()获取被按下的键盘是哪个键,这两个函数可以立即获取键盘被按下的那个键,而不像cin>>那样需要先输入再回车,该程序实现了摁下空格开始录制,再摁下空格暂停录制,摁下ESC键退出视频录制。

String videoFile = parser.get("sourceFile"); 

	string fileName = parser.get("dstFile"); 

	char flag; 

	int ch; 

	int num = 0; 

    // Check if params are correctly parsed in his variables 

    if (!parser.check()) 

    { 
        parser.printErrors(); 

        return 0; 
    } 
    VideoCapture cap;  

	VideoWriter writer; 

	writer.open(fileName, CV_FOURCC('P', 'I', 'M', '1'), 30.0, Size(640, 480),true); 

    if (videoFile != "0") 
    { 
        cap.open(videoFile);// read a video file 
    } 
	else  

	{  
       cap.open(0);// read the default camera 

    } 

    if (!cap.isOpened())// check if we succeeded 
 
    { 
        return -1; 
    } 
	cout << "请摁下空格键,开始录制视频,摁ESC退出录制" << endl;  

	namedWindow("Video", 1); 

	setMouseCallback("Video", mouseLineHandler, NULL);//定义鼠标回调事件	 

	while (true) 
	{ 
		if (_kbhit() && _getch() == 32)//如果有键盘摁下,该函数返回真 

		{ 
			++num; 
		} 
		else if ((_kbhit() && _getch() == 27))//摁下ESC、 
 
		{ 
			cv::destroyWindow("Video"); 

			cap.release();//录像结束 

			cout << "视频录制结束,摁r键并回车进行回放" << endl; 
 
			break; 

		} 

录制视频结束后,摁下r键可以实现视频回放。

在视频录制的过程中,还可以 进行绘画直线,绘画与视频录制是可以同时进行的,本程序有俩个版本。

版本一:在窗口中可以绘制多条曲线,但是显示出来的就只有一条。

// This is a demo introduces you to reading a video and camera 
#include 
#include 
#include 
#include 
using namespace std;

// OpenCV includes
#include 
#include 
#include 
#include  // for camera
using namespace cv;


/*--------------------------------定义鼠标事件--画直线--------------------------*/
bool got_line = false; 
//全局变量 
Point beginPoint = Point(0, 0);//初始化的(0,0) 

bool got_beigin_point = false; 

Point endPoint = Point(0, 0);//初始化(0,0) 

void mouseLineHandler(int event, int x, int y, int flags, void *param) 
{ 
	switch (event) 
	{ 
		case CV_EVENT_LBUTTONDOWN: 
 
			beginPoint = Point(x, y); 
 
			endPoint = beginPoint; 
 
			got_beigin_point = true; 

			break; 
 
		case CV_EVENT_MOUSEMOVE: 
 
			if (got_beigin_point) 

			{ 
		     	endPoint = Point(x, y); 
			} 

			break; 

		case CV_EVENT_LBUTTONUP: 

			got_line = true; 

			endPoint = Point(x, y); 

			got_beigin_point = false; 
 
			break; 
 
		default: 
 
			break; 
     }
	} 
// OpenCV command line parser functions
// Keys accepted by command line parser
const char* keys = 
{
    "{help h usage ? | | print this message}"
    "{@video |   | Video file, if not defined try to use webcamera}"
	"{camera | 0 | the saved video by opencv}"
	"{sourceFile | 0 | the source video by opencv}"
	"{dstFile | save.avi | the saved video by opencv}"
};

int main(int argc, const char** argv)
{
    CommandLineParser parser(argc, argv, keys);
    parser.about("Reading a video and camera v1.0.0");

    // If requires help show
    if (parser.has("help"))
    {
        parser.printMessage();
        return 0;
    }
	String videoFile = parser.get("sourceFile");
	string fileName = parser.get("dstFile");
	char flag;
	int num = 0;
    // Check if params are correctly parsed in his variables
    if (!parser.check())
    {
        parser.printErrors();
        return 0;
    }
	
    VideoCapture cap; 
	VideoWriter writer;

	writer.open(fileName, CV_FOURCC('P', 'I', 'M', '1'), 30.0, Size(640, 480),true);
    if (videoFile != "0")
    {
        cap.open(videoFile);// read a video file
    }
	else 
	{
        cap.open(0);// read the default camera
    }
    if (!cap.isOpened())// check if we succeeded
    {
        return -1;
    }
	cout << "请摁下空格键,开始录制视频,摁ESC退出录制" << endl; 
	namedWindow("Video", 1);
	setMouseCallback("Video", mouseLineHandler, NULL);//定义鼠标回调事件	
	while (true)
	{
		if (_kbhit() && _getch() == 32)//如果有键盘摁下,该函数返回真
		{
			++num;
		}
		else if ((_kbhit() && _getch() == 27))//摁下ESC、
		{
			cv::destroyWindow("Video");
			cap.release();//录像结束
			cout << "视频录制结束,摁r键并回车进行回放" << endl;
			break;
		}
		Mat frame;
		switch(num%2)
		{
	    	case 0:
		        break;			
			case 1:
							
				cap >> frame; // get a new frame from camera 
			//画直线 

 				if (got_beigin_point || got_line) 

 				{ 
       				line(frame, beginPoint, endPoint, Scalar(0, 0, 255), 2); 

 				} 
	  				
                imshow("Video", frame); 

 				writer << frame;//write a new frame in an output file 

 				imshow("Video", frame); 
 
				waitKey(1000 / 30); 

 				break; 
			
		}
		
		
	}
	cin >> flag;
	if (flag == 'r')
	{
		cap.open(".//"+fileName);
		while (1)
		{
			Mat frame;
			cap >> frame;
			if (!frame.data)
			{
				break;
			}
			imshow("reShowVideo", frame);
			waitKey(1000 / 30);
		}
		cout << "视频回放结束!" << endl;
		cv::destroyWindow("reShowVideo");
	} 
	else
	{
		cout << "不需要回放,直接退出" << endl;
	}
	system("pause");
    // Release the camera or video file
	writer.release();
    cap.release();
    return 0;
	
}

版本二:视频录制过程中可以画直线,并显示所有已经绘画出的直线

源码:https://download.csdn.net/download/weixin_28949185/10830852

你可能感兴趣的:(opencv,'OPENCV,视频保存,视频回放,视频画线,摄像头)