opencv视频读写和视频等间隔采样
今天學習了opencv的HighGUI的內容
總結了兩個視頻讀寫demo以備以后進行視頻處理和識別用
demo1 視頻的讀取和寫入
按順序讀取視頻的每一幀。對于讀取的每一幀圖像,顯示在窗口中,然后轉化為灰度圖像輸出到指定的文件中。
運行期間可以按ESC鍵退出。
還可以用鼠標調整滾動條來動態改變視頻的播放位置。滾動條的位置≈想要播放的幀在整個視頻中的位置
比如將滾動條調整到如下圖所示位置,直接將視頻跳轉到視頻總長度一半的位置開始播放
滾動條的位置≈想要播放的幀在整個視頻中的位置 ?這里之所以是“約等于”,是因為opencv采用的幀定位的函數默認使用的是關鍵幀的定位方式,導致視頻跳轉的位置并不準確。
具體可以參見SetCaptureProperty定位不準的原因
另外有個容易出錯的地方,創建視頻寫入器的命令:CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('X','V','I','D'), fps1, size1,0);
最后有個參數是0,表示輸出的視頻文件是灰度的。如果不設置,默認的參數取值為1,代表輸出的視頻文件是彩色的。如果此時將圖像轉換成灰度圖后輸出。運行視頻文件是系統會提示錯誤。
對于這一點的描述可以參見opencv彩色圖像轉灰度圖像失敗的原因
demo1的源代碼如下:
#include <iostream> #include <cv.h> #include <cxcore.h> #include <highgui.h>// 使用標準命名空間 using namespace std;// 初始化進度條的位置 int g_slider_position1 = 0;//初始化視頻捕獲器 CvCapture* g_capture1 = NULL;// 定義回調函數用于播放進度的控制 void onTrackbarSlide1( int pos1 ) {cvSetCaptureProperty( g_capture1, CV_CAP_PROP_POS_FRAMES, pos1 ); }int main(int argc, char** argv ) {// 建立播放窗口cvNamedWindow( "Video Test 1", CV_WINDOW_AUTOSIZE );// 捕捉視頻文件char video1[] = "yssh.avi";//創建指定視頻文件的捕獲器g_capture1 = cvCreateFileCapture( video1 );// 讀取視頻文件的總幀數并顯示int frames1 = (int) cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FRAME_COUNT );cout << "總幀數 = " << frames1 << endl;// 讀取視頻文件每秒顯示幀數信息double fps1 = cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FPS );cout << "fps1 = " << fps1 << endl;//讀取視頻文件每幀圖像大小信息CvSize size1 = cvSize( (int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_WIDTH),(int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_HEIGHT));// 建立進度條if( frames1 != 0 )cvCreateTrackbar( "Position", "Video Test 1", &g_slider_position1, frames1, onTrackbarSlide1);// 創建 VideoWriter char out1[] = "out1.avi";//CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('M','J','P','G'), fps1, size1,0);//創建視頻寫入器CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('X','V','I','D'), fps1, size1,0);// 記錄視頻的某一幀IplImage* frame1;//記錄視頻某一幀轉換后的灰度圖像IplImage* gray1 = cvCreateImage(size1, 8, 1);//讀取并播放視頻,直至播放結束/主動退出while( true ){// 獲取源文件的一幀畫面frame1 = cvQueryFrame( g_capture1 );if( !frame1 ) break;//顯示這一幀cvShowImage( "Video Test 1", frame1 );// 將當前幀轉換為灰度圖像cvCvtColor(frame1 ,gray1, CV_RGB2GRAY);// 保存:將當前幀(灰度圖)寫入到目標視頻文件cvWriteFrame( wrVideo1, gray1 );// 若按下 ESC 鍵,則退出程序char c = cvWaitKey(33);if( c == 27 ) break; }// 釋放內存,關閉窗口cvReleaseCapture( &g_capture1 );cvReleaseVideoWriter( &wrVideo1 );cvDestroyWindow( "Video Test 1" );return 0; }
demo2?視頻等間隔采樣
程序按順序讀取視頻的每一幀,對于滿足固定間隔的幀圖像,顯示并輸入,不滿足的直接跳過。
這個demo可以用于等間隔的從視頻中抽取圖像,以備以后進行視頻處理和識別用
demo2的源代碼如下:
#include <iostream> #include <cv.h> #include <cxcore.h> #include <highgui.h>// 使用標準命名空間 using namespace std;//初始化視頻捕獲器 CvCapture* g_capture1 = NULL;int main(int argc, char** argv ) {// 建立播放窗口cvNamedWindow( "Video Test 1", CV_WINDOW_AUTOSIZE );// 捕捉視頻文件char video1[] = "yssh.avi";//創建指定視頻文件的捕獲器g_capture1 = cvCreateFileCapture( video1 );// 讀取視頻文件的總幀數并顯示int TotalFrames = (int) cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FRAME_COUNT );cout << "總幀數 = " << TotalFrames << endl;// 讀取視頻文件每秒顯示幀數信息double fps1 = cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FPS );cout << "fps1 = " << fps1 << endl;//讀取視頻文件每幀圖像大小信息CvSize size1 = cvSize( (int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_WIDTH),(int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_HEIGHT));//CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('M','J','P','G'), fps1, size1,0);//創建視頻寫入器VideoWriterchar out1[] = "IntervalOutput.avi";CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('X','V','I','D'), fps1, size1,0);// 記錄視頻的某一幀IplImage* frame1;//記錄視頻某一幀轉換后的灰度圖像IplImage* gray1 = cvCreateImage(size1, 8, 1);int position=0;int interval=10; //這里指定一個抽取視頻間隔//讀取并播放視頻,直至播放結束/主動退出while( true ){// 先獲取源文件的一幀畫面frame1 = cvQueryFrame( g_capture1 );if( !frame1 ) //視頻讀取完畢break; position=(int)cvGetCaptureProperty( g_capture1, CV_CAP_PROP_POS_FRAMES);if(position%interval!=0) continue;//顯示這一幀cvShowImage( "Video Test 1", frame1 );// 將當前幀轉換為灰度圖像cvCvtColor(frame1 ,gray1, CV_RGB2GRAY);// 保存:將當前幀(灰度圖)寫入到目標視頻文件cvWriteFrame( wrVideo1, gray1 );// 若按下 ESC 鍵,則退出程序char c = cvWaitKey(33);if( c == 27 ) break; }// 釋放內存,關閉窗口cvReleaseCapture( &g_capture1 );cvReleaseVideoWriter( &wrVideo1 );cvDestroyWindow( "Video Test 1" );return 0; }總結
以上是生活随笔為你收集整理的opencv视频读写和视频等间隔采样的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 风机桨叶故障诊断(七) 滑动窗与非极大值
- 下一篇: Modbus协议栈开发笔记之二:Modb