目录
一、VideoCapture()类的常用API接口
1.构造VideoCapture()对象实例
C++版本
cv::VideoCapture::VideoCapture(const string& filename); //input filename
cv::VideoCapture::VideoCapture(int device); //video capture denice id
cv::VideoCapture::VideoCapture();
Python版本
cap=cv2.VideoCapture(filename)
cap=cv2.VideoCapture(device)
cap=cv2.VideoCapture()
功能:
创建一个VideoCapture类的实例,如果传入对应的参数,可以直接打开视频文件或者要调用的摄像头。
参数:
filename代表视频文件的路径,这时会打开指定路径下的视频(.avi,.mpg,.mp4)等等,也可以是图片序列(.jpg文件序列)或者视频流的网址。请注意,每个视频流或IP摄像机源均具有其自己的URL方案。
device为整型变量,参数是0,表示打开笔记本的内置摄像头;参数是1,则打开外置摄像头;其他数字则代表其他设备。通常来说,它是区分不同摄像头的一个标识码,如果在当前系统下只有一个摄像头时参数为0,当有多个摄像头同时处于当前系统之中时,参数随之递增即可。参数为 -1时单独出现窗口,选取相应编号摄像头。
备注:
对于C++版本,也可以先对对象进行实例化,再使用open函数初始化。
bool cv::VideoCapture::open(const string& filename);
bool cv::VideoCapture::open(int device);
bool cv::VideoCapture::isOpened();
功能:对已经定义的VideoCapture类的实例进行初始化,传入对应的参数,可以直接打开视频文件或者要调用的摄像头。
参数:与前面构建对象实例的参数相同。如果成功读取视频或者调用摄像头则返回true,否则返回false。
这样我们有两种方法构建VideoCapture()对象实例
//先实例化再初始化
cv::VideoCapture capture;
capture.open("cat.avi");
//同时实例化和初始化
cv::VideoCapture capture("cat.avi");
2.利用VideoCapture()读取图片
C++版本
bool cv::VideoCapture::grab();
bool cv::VideoCapture::retrieve(Mat& image, int channel=0);
VideoCapture& cv::VideoCapture::operator>>(Mat& image);
bool cv::VideoCapture::read(Mat& image);
grab() 功能:从视频文件或捕获设备中抓取下一个帧,假如调用成功返回true。
retrieve() 功能:解码并且返回刚刚抓取的视频帧,假如没有视频帧被捕获(相机没有连接或者视频文件中没有更多的帧)将返回false。
read() 功能:该函数结合grab()和retrieve()其中之一被调用,用于捕获、解码和返回下一个视频帧。假如没有视频帧被捕获(相机没有连接或者视频文件中没有更多的帧)将返回false。
这样C++版本有四种读取方式
capture.read(frame);
capture.grab();
capture.retrieve(frame);
capture >> frame;
Python版本
ret,image=cap.read()
功能:cap.read()按帧读取视频,ret,frame是获cap.read()方法的两个返回值。其中ret是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,它的返回值就为False。frame就是每一帧的图像,是个三维矩阵。
3.利用VideoCapture()获取和设置摄像头或者视频参数信息
C++版本
double cv::VideoCapture::get(int propid); //property identfier(see table)
bool cv::VideoCapture::set(int propid, double value);
Python版本`
value=cap.get(propid)
cap.set(propid,value)
功能:我们通过get()和set()函数分别可以获取和设置摄像头或者视频参数信息,
参数:包括的参数信息如下表:
4.释放VideoCapture()对象
C++版本
void cv::VideoCapture::release();
Python版本
cap.release()
功能:关闭视频文件或者摄像头。
二、VideoWriter()类的常用API接口
1.构造VideoWriter()对象实例
C++版本
cv::VideoWriter::Videowriter(const String &filename, int fourcc, double fps, Size frameSize, bool isColor=true);
cv::VideoWriter::VideoWriter(const String &filename, int apiPreference, int fourcc, double fps, Size frameSize, bool isColor=true);
cv::VideoWriter::Videowriter();
Python版本
out=cv2.VideoWriter(filename, fourcc, fps, frameSize,isColor=true)
out=cv2.VideoWriter()
功能:创建一个VideoWriter类的实例。
参数:
filename输出视频文件的名称。
fourcc用于压缩帧视频轨道的编解码器的4个字符的代码。现在所有的视频解码器都有唯一的短名称,最多4个字符。常见的有XVID,DVIX和H264。
例如:
VideoWriter :: fourcc(‘P’,‘I’,‘M’,‘1’)是MPEG-1编解码器;
VideoWriter :: fourcc(‘M’,‘J’,‘P’,'G ')是动态jpeg编解码器等。
可以在FOURCC页面的“ 视频编解码器”中获取代码列表。带有MP4容器的FFMPEG后端本机使用其他值作为fourcc代码:请参见ObjectType,因此您可能会从OpenCV收到有关fourcc代码转换的警告消息。
fps代表创建的视频流的帧率,这是输出视频的每秒帧数。
frameSize代表视频帧的大小(长宽)。
isColor默认情况是True。如果为True,则编码器将期望并编码彩色帧,否则它将与灰度帧一起使用(仅Windows当前支持该标志)。
备注:
对于C++版本,也可以先对对象进行实例化,再使用open函数初始化。
bool cv::VideoWriter::open(const String &filename,int fourcc, double fps,Size frameSize,bool isColor=true);
bool cv::VideoWriter::open(const String &filename, int apiPreference, int fourcc, double fps, Size frameSize, bool isColor=true);
bool cv::VideoWriter::isOpened();
功能:对已经定义的VideoWriter类的实例进行初始化,传入对应的参数。
参数:与前面构建对象实例的参数相同。如果成功打开视频编写器则返回true,否则返回false。
这样我们有两种方法构建VideoWriter()对象实例
int vedio_width = capture.get(cv::CAP_PROP_FRAME_WIDTH);
int vedio_height = capture.get(cv::CAP_PROP_FRAME_HEIGHT);
std::string outputVideoPath = "..\\test.avi";
//先实例化再初始化
cv::VideoWriter video;
video.open(outputVideoPath,cv::VideoWriter::fourcc('M', 'P', '4', '2'), 25, cv::Size(vedio_width, vedio_height));
//同时实例化和初始化
cv::VideoWriter video(outputVideoPath,cv::VideoWriter::fourcc('M', 'P', '4', '2'), 25, cv::Size(vedio_width, vedio_height));
2.利用VideoWriter()写入视频
C++版本
VideoWriter& cv::VideoWriter::operator<<(Mat& image);
void cv::VideoWriter::write(InputArray image);
功能:将指定的图像写入视频文件。它的大小必须与打开视频编写器时指定的大小相同。通常,彩色图像应采用BGR格式。
这样C++版本有两种读取方式
video.write(frame);
capture << frame;
Python版本
out.write(frame)
3.利用VideoWriter()获取和设置视频写入器属性
C++版本
double cv::VideoWriter::get(int propid); //property identfier(see table)
bool cv::VideoWriter::set(int propid, double value);
Python版本`
value=out.get(propid)
out.set(propid,value)
功能:我们通过get()和set()函数分别可以获取和设置VideoWriter()属性标识符或视频I / O API后端的其他标志之一。
参数:这里的属性就不一一赘述了,大家可以去参考opencv官方文档中的cv :: VideoWriterProperties。
4.释放VideoWriter()对象
C++版本
void cv::VideoWriter::release();
Python版本
out.release()
功能:关闭视频文件或者摄像头。
三、打开摄像头并按格式保存视频和每帧图片
1.C++版本
#include <iostream>
#include<string.h>
#include<fstream>
#include<Windows.h>
#ifdef _WIN32
#define OPENCV
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <fstream>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2/imgproc/types_c.h>
#include <math.h>
#include <opencv2/core/core.hpp>
#include <opencv2/ml/ml.hpp>
using namespace std;
using namespace cv;
using namespace ml;
int device = 1;
int i_begin = 0;
int width = 1280;
int height = 720;
double fps = 25.0;
std::string outputVideoPath = "test\\";
std::string outputVideoName = "test.avi";
std::string outputPicturePath = "Latest\\";
std::string outputPictureFormat = ".jpg";
std::string imshowWindowName = "result";
int quit = 'q';
int fourcc = cv::VideoWriter::fourcc('M', 'P', '4', '2');
int waitkey_time = 100;
int main()
{
cv::VideoCapture capture(device);
if (!capture.isOpened()) //判断是否成功打开相机
{
return -1;
}
capture.set(cv::CAP_PROP_FRAME_WIDTH, width); //设置捕获视频的宽度
capture.set(cv::CAP_PROP_FRAME_HEIGHT, height); //设置捕获视频的高度
int vedio_width = capture.get(cv::CAP_PROP_FRAME_WIDTH); //获取图像的宽度
int vedio_height = capture.get(cv::CAP_PROP_FRAME_HEIGHT); //获取图像的高度
cv::VideoWriter video(outputVideoPath+ outputVideoName, fourcc, fps, cv::Size(vedio_width, vedio_height));
while (true)
{
cv::Mat frame;
capture >> frame;
if (frame.empty())
continue;
cv::namedWindow(imshowWindowName, CV_WINDOW_NORMAL);
cv::imshow(imshowWindowName, frame);
cv::imwrite(outputPicturePath + to_string(i_begin) + outputPictureFormat, frame);
i_begin++;
video << frame;
int q=cv::waitKey(waitkey_time);
if (q == quit)
break;
}
capture.release();
video.release();
cv::destroyAllWindows();
return 0;
}
2.Python版本
import cv2
device=1
i_begin=0
width,height=1280,720
fps=25.0
outputVideoPath='test/'
outputVideoName='test.avi'
outputPicturePath='Latest/'
outputPictureFormat='.jpg'
imshowWindowName='result'
quit='q'
fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', '2')
waitkey_time = 100
cap=cv2.VideoCapture(device)
cap.set(cv2.CAP_PROP_FRAME_WIDTH,width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT,height)
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
out=cv2.VideoWriter(outputVideoPath+outputVideoName, fourcc, fps, size)
while(cap.isOpened()):
ret,image=cap.read()
if ret==False:
break
cv2.namedWindow(imshowWindowName, cv2.WINDOW_NORMAL)
cv2.imshow(imshowWindowName,image)
cv2.imwrite(outputPicturePath+str(i_begin)+outputPictureFormat,image)
i_begin+=1
out.write(image)
if cv2.waitKey(waitkey_time) & 0xFF==ord(quit):
break
cap.release()
out.release()
cv2.destroyAllWindows()
3.参数说明
device为0表示打开笔记本的内置摄像头,device为1或更大,则打开外置摄像头或其他设备。
i_begin表示保存的每帧图片是从i_begin.jpg开始命名的,后面依次递增。
width,height为设置摄像头拍摄图片的宽度和高度。
fps为创建的视频流的帧率。
outputVideoPath和outputVideoName分别表示保存视频的路径和名称。
outputPicturePath和outputPictureFormat分别表示保存每一帧图片的路径和名称。
imshowWindowName表示显示每一帧图片窗口的名称。
quit表示该字符被按下,摄像头关闭。
fourcc表示压缩帧视频轨道的编解码器的4个字符的代码。
waitkey_time表示等待按键按下时间,也可以作为设置摄像间隔帧率的时间。
4.运行结果
在运行之前,我们需要在代码所在的目录下手动创建test和Latest两个文件夹。之后启用内置摄像头或插上外置摄像头,运行程序,将会跳出窗口,显示摄像头拍摄的内容。键盘输入q,则摄像头和窗口关闭。这时候会在test文件夹中找到保存的test.avi视频,在Latest文件夹中找到命名为0.jpg,1.jpg,2.jpg,…的连续帧图片。
四、视频转化为连续帧的图片
1.C++版本
#include <iostream>
#include<string.h>
#include<fstream>
#include<Windows.h>
#ifdef _WIN32
#define OPENCV
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <fstream>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2/imgproc/types_c.h>
#include <math.h>
#include <opencv2/core/core.hpp>
#include <opencv2/ml/ml.hpp>
using namespace std;
using namespace cv;
using namespace ml;
std::string inputVideoPath = "sp\\";
std::string inputVideoName = "test.avi";
int i_begin = 0;
std::string outputPicturePath = "sq\\";
std::string outputPictureFormat = ".jpg";
std::string imshowWindowName = "result";
int quit = 'q';
int main()
{
cv::VideoCapture capture(inputVideoPath+inputVideoName);
if (!capture.isOpened())
{
return -1;
}
int vedio_width = capture.get(cv::CAP_PROP_FRAME_WIDTH); //获取图像的宽度
int vedio_height = capture.get(cv::CAP_PROP_FRAME_HEIGHT);
float video_fps = capture.get(cv::CAP_PROP_FPS);
cout << "width:" << vedio_width << '\n' << "height:" << vedio_height << '\n' << "fps:" << video_fps;
int waitkey_time = int(1000 / video_fps);
while (true)
{
cv::Mat frame;
capture >> frame;
if (frame.empty())
break;
cv::namedWindow(imshowWindowName, CV_WINDOW_NORMAL);
cv::imshow(imshowWindowName, frame);
cv::imwrite(outputPicturePath + to_string(i_begin) + outputPictureFormat, frame);
i_begin++;
int q = cv::waitKey(waitkey_time);
if (q == quit)
break;
}
capture.release();
cv::destroyAllWindows();
return 0;
}
2.Python版本
import cv2
inputVideoPath='sp/'
inputVideoName='test.avi'
i_begin=0
outputPicturePath='sq/'
outputPictureFormat='.jpg'
imshowWindowName='result'
quit='q'
cap=cv2.VideoCapture(inputVideoPath+inputVideoName)
vedio_width=int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
vedio_height=int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
vedio_fps=float(cap.get(cv2.CAP_PROP_FPS))
print("width:",vedio_width)
print("height:",vedio_height)
print("fps:",vedio_fps)
waitkey_time=int(1000/vedio_fps)
while(cap.isOpened()):
ret,image=cap.read()
if ret==False:
break
cv2.namedWindow(imshowWindowName, cv2.WINDOW_NORMAL)
cv2.imshow(imshowWindowName,image)
cv2.imwrite(outputPicturePath+str(i_begin)+outputPictureFormat,image)
i_begin+=1
if cv2.waitKey(waitkey_time) & 0xFF==ord(quit):
break
cap.release()
cv2.destroyAllWindows()
3.参数说明
inputVideoPath和inputVideoName分别表示所要打开视频的路径和名称。
i_begin表示保存的每帧图片是从i_begin.jpg开始命名的,后面依次递增。
outputPicturePath和outputPictureFormat分别表示保存每一帧图片的路径和名称。
imshowWindowName表示显示每一帧图片窗口的名称。
quit表示该字符被按下,视频关闭。
4.运行结果
在运行之前,我们需要在代码所在的目录下手动创建sp和sq两个文件夹,并且将要打开的视频test.avi放在sp文件夹中。之后运行程序,将会跳出窗口,显示视频内容。键盘输入q,则视频和窗口关闭。这时候会在sq文件夹中找到命名为0.jpg,1.jpg,2.jpg,…的连续帧图片。
五、连续帧的图片转化为视频
1.C++版本
#include <iostream>
#include<string.h>
#include<fstream>
#include<Windows.h>
#ifdef _WIN32
#define OPENCV
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui_c.h>
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <fstream>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2/imgproc/types_c.h>
#include <math.h>
#include <opencv2/core/core.hpp>
#include <opencv2/ml/ml.hpp>
using namespace std;
using namespace cv;
using namespace ml;
std::string inputPicturePath = "pp\\";
std::string inputPictureFormat = ".jpg";
int i_begin = 0;
double fps = 25.0;
std::string outputVideoPath = "qq\\";
std::string outputVideoName = "test.avi";
std::string imshowWindowName = "result";
int quit = 'q';
int fourcc = cv::VideoWriter::fourcc('M', 'P', '4', '2');
int waitkey_time = int(1000/fps);
int main()
{
cv::Mat frame=cv::imread(inputPicturePath + to_string(i_begin) + inputPictureFormat);
if (frame.empty())
return -1;
int picture_width = frame.cols;
int picture_height = frame.rows;
cout << "width:" << picture_width << '\n' << "height:" << picture_height;
cv::VideoWriter video(outputVideoPath + outputVideoName, fourcc, fps, cv::Size(picture_width, picture_height));
while (true)
{
cv::Mat frame = cv::imread(inputPicturePath + to_string(i_begin) + inputPictureFormat);
if (frame.empty())
break;
cv::namedWindow(imshowWindowName, CV_WINDOW_NORMAL);
cv::imshow(imshowWindowName, frame);
i_begin++;
video << frame;
int q = cv::waitKey(waitkey_time);
if (q == quit)
break;
}
video.release();
cv::destroyAllWindows();
return 0;
}
2.Python版本
import cv2
inputPicturePath='pp/'
inputPictureFormat='.jpg'
i_begin=0
fps=25.0
outputVideoPath='qq/'
outputVideoName='test.avi'
imshowWindowName='result'
quit='q'
fourcc = cv2.VideoWriter_fourcc('M', 'P', '4', '2')
waitkey_time = int(1000/fps)
image=cv2.imread(inputPicturePath + str(i_begin) + inputPictureFormat)
try:
image.shape
except:
exit()
picture_width = image.shape[1];
picture_height = image.shape[0];
size = (int(picture_width), int(picture_height))
print("width:",picture_width)
print("height:",picture_height)
out=cv2.VideoWriter(outputVideoPath+outputVideoName, fourcc, fps, size)
while(out.isOpened()):
image=cv2.imread(inputPicturePath + str(i_begin) + inputPictureFormat)
try:
image.shape
except:
break
cv2.namedWindow(imshowWindowName, cv2.WINDOW_NORMAL)
cv2.imshow(imshowWindowName,image)
i_begin+=1
out.write(image)
if cv2.waitKey(waitkey_time) & 0xFF==ord(quit):
break
out.release()
cv2.destroyAllWindows()
3.参数说明
inputPicturePath和inputPictureFormat分别表示所要读取连续帧图片的路径和名称。
i_begin表示保存的每帧图片是从i_begin.jpg开始命名的,后面依次递增。
fps为创建的视频流的帧率。
outputVideoPath和outputVideoName分别表示保存视频的路径和名称。
imshowWindowName表示显示每一帧图片窗口的名称。
quit表示该字符被按下,停止读取连续帧图片。
fourcc表示压缩帧视频轨道的编解码器的4个字符的代码。
waitkey_time表示等待按键按下时间,也可以作为设置读取图片的时间。
4.运行结果
在运行之前,我们需要在代码所在的目录下手动创建pp和qq两个文件夹,并且将命名为0.jpg,1.jpg,2.jpg,…的连续帧图片放在pp文件夹中。之后运行程序,将会跳出窗口,显示连续帧图片内容。键盘输入q,则连续帧图片和窗口关闭。这时候会在qq文件夹中找到新生成的视频test.avi。