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