opencv從入門到精通(1)-建立自己的視訊播放器
阿新 • • 發佈:2019-02-02
本文預設你已經成功配置opencv並具有一定的c++基礎,後續將由淺入深地介紹如何運用opencv進行影象處理與機器學習的具體實踐,在熟悉opencv的同時也能對相關理論有更深刻的理解。opencv的具體配製方法參見:http://www.cnblogs.com/woshitianma/p/3853447.html。
第一個程式——展示一個影象
c++中通過檔案流可以將影象從磁碟中讀入,處理後再輸出到磁碟,但無法在螢幕上顯示,運用opencv中的HighGUI工具箱則可以達到螢幕上及時顯示的效果。 首先在visual studio中建立一個空的win32專案,新建一個cpp檔案,輸入下面的程式碼,並將影象檔案放到專案的檔案目錄中。在解決方案資源管理器中可以開啟專案所在資料夾。
程式碼如下:
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main()
{
IplImage* img = cvLoadImage("a1.ppm");
//IplImage是opencv中處理影象的資料結構,支援所有影象格式。
//cvLoadImage函式讀入影象"a1.ppm",返回一個指標變數。
cvNamedWindow("Example1",CV_WINDOW_AUTOSIZE);
//cvNamedWindow函式建立一個名為"Example1"的視窗,第二個參 //數CV_WINDOW_AUTOSIZE表示視窗大小自動調整與影象大小相同
cvShowImage("Example1",img);
//cvShowImage將影象img在視窗Example中顯示出來。
cvWaitKey(0);
//cvWaitKey函式功能是等待雙擊事件,雙擊後退出。
cvReleaseImage(&img);//釋放影象記憶體
cvDestroyWindow("Example1");//釋放視窗記憶體
}
第二個程式-展示AVI視訊
具體情形與影象差不多,但要設定一個迴圈來讀取每一幅畫面,同時能在視訊結束或者你不想看時退出迴圈。
程式碼:
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main()
{
cvNamedWindow("Example2",CV_WINDOW_AUTOSIZE);//建立視窗
CvCapture* capture=cvCreateFileCapture("a2.mp4");
//cvCreateFileCapture函式作用是載入視訊"a2.mp4"並返回指標到
//視訊資料結構CvCapture建立的變數capture中,這時capture便包含視訊 //中的所有資訊。
IplImage* frame;//建立變數frame
while(1){
frame=cvQueryFrame(capture);/*cvQueryFrame的引數為CvCapture結構的指標。用來將下一幀視訊檔案載入記憶體,返回一個對應當前幀的指標。與cvLoadImage不同的是cvLoadImage為影象分配記憶體空間,而cvQueryFrame使用已經在cvCapture結構中分配好的記憶體。*/
if(!frame) break;//frame為空時退出迴圈
cvShowImage("Example2",frame);//顯示當前畫面
char c=cvWaitKey(33);//等待33毫秒,如有按鍵,將值賦給c
if(c==27) break;/*如果按鍵是“Esc”鍵(ASCLL 27),結束迴圈*/
}
cvReleaseCapture(&capture);
cvDestroyWindow("Example2");
}
簡單的視訊播放器
接下來介紹cvSetCaptureProperty等函式在視訊播放中加入進度條,這樣就可以取得調戲自己家的進度條成就了。程式碼及註釋如下:
#include <stdio.h>
#include <fstream>
#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int g_slider_position = 0;
CvCapture* g_capture = NULL;
//定義onTrackbarSlide回撥函式來輸入滾動條的位置pos
void onTrackbarSlide(int pos) {
cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos);
/*cvSetCaptureProperty函式用於設定capture結構的各種屬性,CV_CAP_PROP_POS_FRAMES表示以幀數來設定讀入位置。*/
}
int main( ) {
cvNamedWindow( "Example3", CV_WINDOW_AUTOSIZE );
g_capture = cvCreateFileCapture( "a2.mp4" );
IplImage *foo = cvQueryFrame( g_capture);
//獲取視訊的幀數、畫面的長和寬
int frames = (int) cvGetCaptureProperty(g_capture, CV_CAP_PROP_FRAME_COUNT );
int tmpw = (int) cvGetCaptureProperty(g_capture,CV_CAP_PROP_FRAME_WIDTH);
int tmph = (int) cvGetCaptureProperty( g_capture, CV_CAP_PROP_FRAME_HEIGHT );
printf("opencv frames %d w %d h %d\n",frames,tmpw,tmph);
cvCreateTrackbar( "Position", "Example3", &g_slider_position, frames, onTrackbarSlide );/*
cvCreateTrackbar函式用於建立進度條,引數含義:Position-進度條名字;Example3-需要加入進度條的視窗名字
&g_slider_position整數指標,它的值將反映滑塊的位置。這個變數指定建立時的滑塊位置;frames-滑塊位置的最大值。
onTrackbarSlide-回撥函式的指標*/
IplImage* frame;
frames = 0;
while(1) {
frame = cvQueryFrame( g_capture );
if( !frame ) break;
int frames = cvGetCaptureProperty( g_capture, CV_CAP_PROP_POS_FRAMES);//返回當前進度條位置對應的幀數
frames++;
cvSetTrackbarPos("Position","Example3",frames);//自動控制滾條位置
cvShowImage( "Example3", frame );
char c = (char)cvWaitKey(10);
if( c == 27 ) break;
}
cvReleaseCapture( &g_capture );
cvDestroyWindow( "Example3" );
return 0;
}