OpenCV簡介與安裝
836
2025-03-31
第一個程序:顯示圖片
OpenCV提供了一些實用工具來讀取從視頻流到攝像機畫面的各種各樣的圖像格式,這些工具都是HighGUI的一部分。我們將使用其中的一些工具來創建一個簡單的程序,這個程序將打開一張圖像并且將其顯示在屏幕上(如示例2-1所示)。
#include
int main( int argc, char** argv ) {?? cv::Mat img = cv::imread(argv[1],-1);?? if( img.empty() ) return -1;
cv::namedWindow( "Example1", cv::WINDOW_AUTOSIZE );?? cv::imshow( "Example1", img );?? cv::waitKey( 0 );?? cv::destroyWindow( "Example1" );?? return 0;
}
注意,OpenCV的函數都位于cv這一命名空間下,為了調用OpenCV的函數,你需要在每個函數前加上cv::,向編譯器說明你所調用的函數處于cv命名空間。為了擺脫這種繁瑣的工作,我們可以像示例2-2一樣用using namespace cv;指令,告訴編譯器假設所有函數都位于cv命名空間下。注1你還需要注意示例2-1和示例2-2在頭文件上的不同,在前者中,我們使用了通用的opencv.hpp,而在后者中,我們只使用了必須的頭文件來節約編譯時間。
示例2-2:與示例2-1不同的是直接使用了using namespace
#include "opencv2/highgui/highgui.hpp" using namespace cv; int main( int argc, char** argv ) {
Mat img = imread( argv[1], -1 );?? if( img.empty() ) return -1;
注1: 當然,如果這樣做,需要冒著和其他潛在的命名空間沖突的風險。如果函數foo()已經存在于cv和std的命名空間,你必須指定自己使用的是位于cv::foo()的函數還是位于 std::foo()的函數。在本書中,除了示例2-2,都會指明cv::命名空間,并以此保持一個良好的編程風格。
namedWindow( "Example1", cv::WINDOW_AUTOSIZE );?? imshow( "Example1", img );?? waitKey( 0 );
destroyWindow( "Example1" );
}
當使用命令行編譯和運行時,注2示例2-1將加載一張圖像到內存中并且顯示到屏幕上。它會保持顯示直到用戶按下一個鍵,之后程序才會銷毀窗口并退出。現在讓我們來一行一行地解釋代碼,并花一些時間來理解每一行代碼都在做什么工作。
cv::Mat img = cv::imread( argv[1], -1 );
這一行將會載入圖像。注3函數cv::imread()是高級的;依據文件名來決定載入圖像格式的處理。這也會自動地申請圖像需要的內存,注意,cv::imread()可以讀取很多種圖像格式,包括BMP,DIP,JPEG,JPE,PNG,PBM,PGM,PPM,SR,RAS以及TIFF。函數會返回一個cv::Mat結構,這個結構是OpenCV中你將會接觸最多的自帶結構。
OpenCV使用這個結構來處理所有類型的圖像:單通道、多通道、整型、浮點數以及各種類型。緊接著的下面這一行:
if( img.empty() ) return -1;
檢查這個圖像是否真的被載入了。另一個高層級的函數cv::namedWindow()將會在屏幕打開一個窗口,其中可以包含需要顯示的圖片。
cv::namedWindow( "Example1", cv::WINDOW_AUTOSIZE );
該函數由HighGUI模塊提供,會將一個名稱賦予窗口(在這里窗口名為"Example1")。
未來HighGUI的和這個窗口的交互函數將由這個名稱來指定要與哪個窗***互。
cv::namedWindow第二個參數說明了Windows的特性。這可以全部設置為0(默認情況下),也可以設置為cv::WINDOW_AUTOSIZE。在之前的例子中,窗口的大小將會和載入圖像的大小一致,圖像將會被縮放以適應窗口的大小。在之后的例子中,窗口將會在圖像載入的時候被自動縮放以適應圖像的真實大小,也可能由用戶自行調整。
注2: 當然,如果這樣做的話,你需要冒著和其他潛在的命名空間沖突的風險。如果函數foo() 已經存在于cv和std的命名空間,必須指定你使用的是位于cv::foo()的函數還是位于 std::foo()的函數。在本書中,除了示例2-2,都會指明cv::命名空間,并以此保持一個良好的編程風格。
注3: 好的程序會檢查argv[1]是否存在并且給用戶反饋一個錯誤信息,但是在這里沒有。我們在本書中將會簡略掉這些處理并且假設讀者都有足夠的的知識來理解處理錯誤代碼的方式及其重要性。
cv::imshow( "Example1", img );
不論何時,只要在cv::Mat中擁有一個圖像結構,我們都可以通過cv::imshow() 進行顯示。cv::imshow()將建一個窗口(如果這個窗口不存在,它會自動調用 cv::namedWindow()新建一個窗口)。在調用cv::imshow()的時候,窗口將被重繪上要求的圖片,并且窗口會按照要求自動調整大?。ㄈ绻褂胏v::WINDOW_AUTOSIZE參數)。
cv::waitKey(0);
cv::waitKey(0);函數告訴系統暫停并且等待鍵盤事件。如果其傳入了一個大于零的參數,它將會等待等同于該參數的毫秒時間,然后繼續執行程序。如果參數被設置為0或者一個負數,程序將會無限等待直到有鍵被按下。
因為有cv::Mat,圖像將會在生命周期結束的時候自動釋放,其行為類似于標準模板庫(STL)中的容器類。這種自動的內存釋放由內部的引用指針所控制,最重要的是,這表示我們用不著擔心圖像的內存申請和釋放,這將程序員從OpenCV 1.0 IplImage結構繁瑣的維護工作中解放了出來。
cv::destroyWindow( "Example1" );
最后,我們可以讓窗口自行銷毀。函數cv::destroyWindow()將會關閉窗口并且釋放掉相關聯的內存空間。為了更簡潔的編碼,我們將會在之后的例子中略過這一步。在更長、更復雜的代碼中,程序員應該在窗口的生命周期自然結束之前自主銷毀窗口以防止內存泄漏。
我們下一個任務是創建一個非常簡單的、幾乎和本例一樣的程序來讀取視頻文件。在此之后,我們將會開始對實際圖像進行更多的操作。
OpenCV
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。