攝像頭和視頻的讀取和寫入

總結一下視頻的讀取和寫入,opencv1+和opencv2+以後的版本都總結一下。

先總結一下opencv1+的用法,現在使用的opencv都是2.0以後了,不過1.0版本是使用指針,用起來確實感覺很爽,簡單實用。有人不喜歡1.0+的釋放控件,我覺得這是個好習慣。

視頻讀入:

int main(int argc,char* argv[] )
{
	//argv[1] input video file
	//argv[2] name of new output file
	argv[1] = ".../12.mp4";
	CvCapture* capture = NULL;
	capture = cvCreateFileCapture(argv[1]);
	if (!capture)
		return - 1;
	IplImage *bgr_frame = cvQueryFrame(capture);
	//幀率,保證播放的正常速度
	double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
	//大小
	CvSize size = cvSize(
		(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH),
		(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT));
	while ((bgr_frame = cvQueryFrame(capture)) != NULL)//(bgr_frame = cvQueryFrame(capture))!=NULL
	{
		cvNamedWindow("capture", 1);
		cvShowImage("capture", bgr_frame);
		cvWaitKey(fps);
	}
	cvReleaseCapture(&capture);
	cvReleaseImage(&bgr_frame);
	return 0;
}
opencv2.0以後的版本讀取方法都是一致的。

int main(int argc, char* argv[])
{
	argv[1] = ".../12.mp4";
	VideoCapture capture(argv[1]);
	if (!capture.isOpened())
	{
		cout << "fail to open" << endl;
		return -1;
	}
	//視頻寬高
	Size videoResolution = Size((int)capture.get(CV_CAP_PROP_FRAME_WIDTH),
		(int)capture.get(CV_CAP_PROP_FRAME_HEIGHT));
	//獲取視頻圖像幀率
	double fps = capture.get(CV_CAP_PROP_FPS);
	//視頻總幀
	double totalFrame = capture.get(CV_CAP_PROP_FRAME_COUNT);
	cout << "總幀數:" << totalFrame << endl;
	cout << "幀率:" << fps << endl;
	cout << "視頻寬、高:" << videoResolution.width << videoResolution.height << endl;
	Mat frameImg;
	while (true)
	{
		capture >> frameImg;
		imshow("frame", frameImg);
		waitKey(fps);
	}
	return 0;
}

opencv1.0+ 寫出視頻操作,做一個簡單的灰度處理吧。opencv1.0有一個需要注意的地方,視頻是不是彩色圖像的問題,有時候不注意IsColor的參數(默認爲1),會造成寫出的視頻只有6k,出現這種情況就需要考慮是不是忽略了這個問題。
處理過程分三步走:
CvVideoWriter* writer = NULL;
	writer = cvCreateVideoWriter(argv[2], CV_FOURCC('M', 'J', 'P', 'G'), fps, size,0);

while(1)
{
cvWriteFrame(writer, bgr_frame);
}
//釋放
cvReleaseVideoWriter(&writer);

灰度化以後在輸出就需要注意兩個方面,第一,前面說的IsColor必須設置爲0,不然寫出的視頻只有6k。第二,就是定義輸出圖像的方式,不能直接定義IplImage* gray_frame; 不然在cvCvtColor處理是會出現格式錯誤。這個是需要注意的,圖片深度是8位,1通道。

IplImage* gray_frame = cvCreateImage(size, IPL_DEPTH_8U, 1);

灰度轉換,不要用錯了:
cvCvtColor(bgr_frame, gray_frame, CV_BGR2GRAY);
//opencv 2.0+的用法
cvtColor(bgr_frame,gray_frame,CV_BGR2GRAY);

完整程序:
int main(int argc,char* argv[] )
{
	//argv[1] input video file
	//argv[2] name of new output file
	argv[1] = ".../12.mp4";
	argv[2] = ".../12out.avi";
	CvCapture* capture = NULL;
	capture = cvCreateFileCapture(argv[1]);
	if (!capture)
		return - 1;
	IplImage *bgr_frame = cvQueryFrame(capture);
	IplImage *gray_frame;
	
	//幀率,保證播放的正常速度
	double fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
	//大小
	CvSize size = cvSize(
		(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH),
		(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT));
	gray_frame = cvCreateImage(size, IPL_DEPTH_8U, 1);
	CvVideoWriter* writer = NULL;
	writer = cvCreateVideoWriter(argv[2], CV_FOURCC('M', 'J', 'P', 'G'), fps, size, 0);

	while ((bgr_frame = cvQueryFrame(capture)) != NULL)//(bgr_frame = cvQueryFrame(capture))!=NULL
	{
		cvCvtColor(bgr_frame, gray_frame, CV_BGR2GRAY);
		cvNamedWindow("capture", 1);
		cvShowImage("capture", bgr_frame);
		cvShowImage("gray_grame", gray_frame);
		cvWriteFrame(writer, gray_frame);
		cvWaitKey(fps);
	}
	cvReleaseCapture(&capture);
	cvReleaseImage(&bgr_frame);
	cvReleaseVideoWriter(&writer);
	return 0;
}
效果:

opencv2.0+的視頻寫出操作:

直接上程序,這種方法很不錯,可以選擇是否進行壓縮。用法是這麼用的。
string outputVideoPath = "...\\input8Write.avi";
	VideoWriter outputVideo;
Size videoResolution = Size((int)video.get(CV_CAP_PROP_FRAME_WIDTH), (int)video.get(CV_CAP_PROP_FRAME_HEIGHT));
	outputVideo.open(outputVideoPath, -1, 25, videoResolution, true);
while(!frame.empty())
{
outputVideo << image;
}
會打開一個視頻壓縮方法:

循環讀取視頻每幀圖像時,最好寫一個判斷,這樣寫出視頻才能跳出,要不然會出現讀完視頻後,一直留在最後一幀,不會自行跳出。
直接貼上程序:

int main(int argc, char* argv[])
{
	argv[1] = ".../12.mp4";
	VideoCapture capture(argv[1]);
	if (!capture.isOpened())
	{
		cout << "fail to open" << endl;
		return -1;
	}
	//視頻寬高
	Size videoResolution = Size((int)capture.get(CV_CAP_PROP_FRAME_WIDTH),
		(int)capture.get(CV_CAP_PROP_FRAME_HEIGHT));
	//獲取視頻圖像幀率
	double fps = capture.get(CV_CAP_PROP_FPS);
	//視頻總幀
	double totalFrame = capture.get(CV_CAP_PROP_FRAME_COUNT);
	cout << "總幀數:" << totalFrame << endl;
	cout << "幀率:" << fps << endl;
	cout << "視頻寬、高:" << videoResolution.width <<"   "<< videoResolution.height << endl;
	string outputVideoPath = "E:/數學建模/12out2.avi";
	VideoWriter outputVideo;
	outputVideo.open(outputVideoPath, CV_FOURCC('M', 'J', 'P', 'G'), fps, videoResolution, true);
	Mat frameImg,grayImage;
	while (true)
	{
		capture >> frameImg;
		if (!frameImg.empty())
		{
			cvtColor(frameImg, grayImage, CV_BGR2GRAY);
			imshow("frame", frameImg);
			imshow("grayImage", grayImage);
			outputVideo << grayImage;
			waitKey(fps);
		}
		else
		{
			break;
		}
		
	}
	return 0;
}





發佈了56 篇原創文章 · 獲贊 72 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章