【学习笔记】Learning OpenCV3——Ch8 working with video

写在前面的话:

最近在做一些视频处理相关的东西,用到OpenCV里的videoIO相关函数,遇到很多坑,查了很多资料和博客,发现Learning OpenCV3是一本很不错的书,现将自己对videoIO这一部分的学习笔记整理在这,以便以后回顾。

  • read
  • write

Reading Video with the cv::VideoCapture Object

对象创建的三种方法:

// 1. Input filename
cv::VideoCapture::VideoCapture(
    const string& filename
);

// 2. Video capture device id
cv::VideoCapture::VideoCapture(
    int device 
);

// 3.
cv::VideoCapture::VideoCapture();

构造函数的第一种:

在第一种方法中,传入视频路径,创建对象后,需要加入视频是否成功打开:

// e.g.
cv::VideoCapture cap("1.mp4");
if (!cap.isOpen()) {
    std::cout << "Failed to open the video" << std::endl;
    return -1;
}

视频打不开的常见原因:

  1. 视频路径错误
  2. 视频编码格式未知

后一种原因的解决方案:

you will need to have the appropriate library already residing on your computer in order to successfully read the video file.

构造函数的第二种:

通常为设备的代号,整型

小tip:

cv::VideoCapture cap(-1); 

可打开一个窗口供以选择捕获视频的设备

构造函数的第三种:

cv::VideoCapture cap;
cap.open("video.avi");

读取视频帧数据

// 1. read function
bool cv::VideoCapture::read(
    cv::OutputArray image // Image into which to read data, return true for read frame successfully, false for failue
);

// 2. >> operator
cv::VideoCapture& cv::VideoCapture::operator>>( cv::Mat& image // Image into which to read data
);
// NOTE:
// << return a reference to the original object, should check the return array is not empty

// 3. grab && retrieve function
bool cv::VideoCapture::grab( void ); // is designed simply to get it onto the computer as quickly as possible
bool cv::VideoCapture::retrieve(
cv::OutputArray image, // Image into which to read data
int channel = 0 // Used for multihead devices
);
// NOTE: 
// can read images from mutiple cameras
// more general

设置&获取视频属性

double cv::VideoCapture::get(
    int propid // Property identifier (see Table 8-4)
);
bool cv::VideoCapture::set(
    int propid,
    double value // Value to which to set the property
);
//Example 8-1. Unpacking a four-character code to identify a video codec
cv::VideoCapture cap( "my_video.avi" );
unsigned f = (unsigned)cap.get( cv::CAP_PROP_FOURCC );
char fourcc[] = {
(char) f, // First character is lowest bits
(char)(f >> 8), // Next character is bits 8-15
(char)(f >> 16), // Next character is bits 16-23
(char)(f >> 24), // Last character is bits 24-31
'\0' // and don't forget to terminate
};

Reading Video with the cv::VideoCapture Object

两种构造方式:

// 1. an uninitialized video object
cv::VideoWriter::VideoWriter();

// 2. an initialized video object
cv::VideoWriter::VideoWriter(
const string& filename, // output filename
int fourcc, // codec, use CV_FOURCC() macro
double fps, // Frame rate (stored in output file)
cv::Size frame_size, // Size of individual images
bool is_color = true // if false, you can pass gray frames
);
// e.g.

Don’t forget that you are providing characters (single quotes), not strings (double quotes).

同cv::VideoCapture,也有cv::VideoWriter::isOpened()方法暗示是否可以写视频,如果返回false,可能存在以下几点原因:

  1. 没有写权限
  2. 编码格式不可用

NOTES:

  1. The codecs available to you depend on your operating system installation and the additional libraries you have installed.
  2. For portable code, it is especially important to be able to gracefully handle the case in which the desired codec is not available on any particular machine.

写入视频的两个函数:

// 1. write function
cv::VideoWriter::write(
    const Mat& image // Image to write as next frame
);
/*
NOTES:
- This image must have the same size as the size you gave to the writer when you configured it in the first place. - If you told the writer that the frames would be in color, this must also be a three-channel image. 
*/

// 2. << Operator
my_video_writer << my_frame;
/*
NOTE:
once you have your video writer open, you can write images to the video stream in the same manner you would write to cout or a file ofstream object
*/

简单实例

#include<opencv2/opencv.hpp>
#include<iostream>

using namespace cv;

int main() {
	// params & input path && output path configure
	int caseVideo = 6;
	char pathInVideo[200], pathOutVideo[200];
	sprintf(pathInVideo, "%d.avi", caseVideo);
	sprintf(pathOutVideo, "%d_output.avi", caseVideo);

	// read video
	cv::VideoCapture cap(pathInVideo);
	if (!cap.isOpened()) {
		std::cerr << "Failed to open the video" << std::endl;
		return -1;
	}
	int frameLength = cap.get(CAP_PROP_FRAME_COUNT);


	//  params for writting output video
	cv::VideoWriter outputVideo;
	cv::Size sWH = cv::Size((int)cap.get(CAP_PROP_FRAME_WIDTH),
		(int)cap.get(CAP_PROP_FRAME_HEIGHT));
	if (!outputVideo.open(pathOutVideo, cv::VideoWriter::fourcc('M', 'P', '4', '2'), cap.get(CAP_PROP_FPS), sWH)) {
		std::cerr << "Failed to write video" << std::endl;
		return -1;
	}

	// gauss filter frame by frame
	for (int i = 0; i < frameLength; i++) {
		std::cout << "Process the " << i << " frame" << std::endl;
		cv::Mat inputImg, outputImg;
		cap.read(inputImg);
		if (!inputImg.empty()) {
			cv::GaussianBlur(inputImg, outputImg, cv::Size(25, 25), 0.0, 0.0);
			outputVideo.write(outputImg);
		}
	}

	// release cap && outputVideo
	cap.release();
	outputVideo.release();

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值