OpenCV初体验
OpenCV提供了一些實用工具來讀取從視頻流到攝像機畫面的各種各樣的圖像格式,這些工具都是HighGUI的一部分。下面幾個小例子可以讓初學者提前體驗一下OpenCV的功能。
1. 打開一張圖像并且將其顯示在屏幕上
#include "stdafx.h" #include <opencv2/opencv.hpp>int main( int argc, char** argv ) {// 載入圖像cv::Mat img = cv::imread("C:\\Users\\Bello\\Desktop\\test.jpg", -1);// 檢查圖像是否真的被載入,如果沒有返回-1,結束程序if ( img.empty() ) return -1;// 由High GUI模塊提供,會將一個名稱賦給窗口,未來High GUI的和這個窗口的交互函數將由這個名稱來指定要與哪個窗口交互。// 第二個參數說明了Windows的特性,這個可以設置為0(默認),也可設為cv::WINDOW_AUTOSIZE,窗口會在圖像載入的時候// 自動縮放以適應圖像的真實大小,也可能由用戶自行調整。cv::namedWindow("Example1", cv::WINDOW_AUTOSIZE );// 將圖像數據顯示為圖像,將建一個窗口(若不存在,會自動調用cv::namedWindow()新建窗口)。cv::imshow( "Example1", img );// 系統(tǒng)暫停并且等待鍵盤事件。// 如果傳入了一個大于0的參數,它將會等待等同于該參數的毫秒數時間,然后繼續(xù)執(zhí)行程序。// 如果參數被設置為0或一個負數,程序將會無限等待知道有鍵被按下。cv::waitKey( 1000 );// 關閉窗口并釋放掉相關聯的內存空間cv::destroyWindow("Example1");return 0; }2. 播放視頻文件
#include "stdafx.h" #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp>int main() {cv::namedWindow( "Example3", cv::WINDOW_AUTOSIZE );// 視頻讀取結構cv::VideoCapture cap;// 視頻讀取結構通過傳入字符串打開文件,這個字符串指示了想要打開的視頻文件的路徑。// 視頻打開后,視頻讀取結構將會包含所有的關于這個視頻文件可以讀取的屬性,包括狀態(tài)信息。cap.open( "D:\\mgtv\\[高清]《媽媽是超人》第二季先導片:安吉“魔音”亂入嚇哭小魚兒 鬼馬精靈包餃子實力坑媽.mp4" );// 聲明一個可以保存視頻幀的結構。cv::Mat frame;for ( ; ; ){// 按照幀從視頻流中讀取視頻文件cap >> frame;// 檢查是否讀取成功if ( frame.empty() ){break;}// 顯示圖片cv::imshow("Example3", frame);// 等待33毫秒,在此等待時間內按任何鍵推出循環(huán),若沒有進行下一層循環(huán)。// 注:設置為33ms是因為這能讓視頻以30FPS的速度播放,并能允許用戶在播放的時候打斷。if(cv::waitKey(33) >= 0 ){break;}}cv::destroyWindow("Example3");return 0; }3. 加入了滑動條的基本瀏覽窗口
// example2-4.cpp: 定義控制臺應用程序的入口點。 //#include "stdafx.h" #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> #include <fstream>using namespace std;// 全局變量,存儲滑動條位置 int g_slider_position = 0; // g_run為1進入單步模式;g_dontset用來避免調整進度條位置的時候觸發(fā)單例模式 int g_run = 1, g_dontset = 0; // 數據讀取結構 cv::VideoCapture g_cap;// 用戶調整滑動條時將觸發(fā)的回調函數,來重新定位視頻讀取的位置 void onTrackbarSlide(int pos, void *) {// 根據滑動條位置重定向視頻讀取位置g_cap.set(cv::CAP_PROP_POS_FRAMES, pos);if (!g_dontset)g_run = 1;g_dontset = 0; }int main() {cv::namedWindow("Example4", cv::WINDOW_AUTOSIZE );g_cap.open("D:\\mgtv\\[高清]《媽媽是超人》第二季先導片:安吉“魔音”亂入嚇哭小魚兒 鬼馬精靈包餃子實力坑媽.mp4");// 確定總幀數int frames = (int)g_cap.get(cv::CAP_PROP_FRAME_COUNT);// 確定視頻的寬度int tmpw = (int)g_cap.get(cv::CAP_PROP_FRAME_WIDTH);// 確定視頻的高度int tmph = (int)g_cap.get(cv::CAP_PROP_FRAME_HEIGHT);// 輸出視頻的信息cout << "Video has " << frames << " frames of dimensions(" << tmpw << ", " << tmph << ")." << endl;// 創(chuàng)建滑動條,第一個參數是滑動條標簽,第二個參數指定窗口,第三個參數是滑動條的初始位置,第四個參數是視頻總幀數,第五個參數是回調函數,不要時可設置為0cv::createTrackbar("Position", "Example4", &g_slider_position, frames, onTrackbarSlide);cv::Mat frame;for (;;) {if (g_run != 0) {// 按幀從視頻流中讀取視頻文件g_cap >> frame;if (frame.empty()){break;}// 獲取當前幀集合讀取的位置int current_pos = (int)g_cap.get(cv::CAP_PROP_POS_FRAMES);g_dontset = 1;// 更新進度條位置,將觸發(fā)回調函數cv::setTrackbarPos("Position", "Example4", current_pos);// 顯示圖片cv::imshow("Example4", frame);// 若為單步模式,那么此運算后g_run為0,則之后的循環(huán)無法進入該語句段;// 若為連續(xù)模式,那么此運算后g_run依舊不為0,所以可以連續(xù)播放視頻。g_run -= 1;}// 從鍵盤輸入獲取值char c = (char)cv::waitKey(10);// 如果按鍵是s,則進入單步模式if (c == 's') {g_run = 1;cout << "Single step, run = " << g_run << endl;}// 如果按鍵是r,則恢復連續(xù)模式else if(c == 'r'){g_run = -1;cout << "Run mode, run = " << g_run << endl;}// 如果按鍵是esc,則退出播放else if(c == 27){break;}}return 0; }對于上述添加滑動條并實現單步模式和連續(xù)模式切換的代碼,邏輯上有一點繞,具體分析如下:
① 初始狀態(tài),g_run=1,g_dontset=0,則采用單步模式。當第一次循環(huán)結束,g_run=0,g_dontset=0,則在不輸入r、s或esc的情況下,不會進入視頻讀取的代碼段,因此圖片顯示會停留在當前狀態(tài)。
② 當按下“s”鍵后,g_run=1,g_dontset=0,和初始狀態(tài)相同,則運行過程如①所示。
③ 當按下“r”鍵后,g_run=-1,g_dontset=0,采用連續(xù)模式。在每次循環(huán)后g_run減少1,則g_run永遠是負值不為0,因此在沒有其他操作情況下,會繼續(xù)執(zhí)行,實現連續(xù)播放。
④ 當手動調整進度條時,沒有進入for循環(huán)中的if,所以g_dontset=0,此時則滿足回調函數中的if條件,則g_run=1,g_dontset=0,和初始狀態(tài)相同,采用單步模式繼續(xù)進行。
⑤ 注意,在系統(tǒng)自動調用回調函數前g_dontset都被賦值為1,因此不會使得g_run=1,單步模式不會生效;只有當用戶手動觸發(fā)滑動條事件時,g_dontset=0,使得回調函數將g_run賦值為1,單步模式生效。
總結
- 上一篇: matlab图像边缘检测分析
- 下一篇: python复制之坑