opencv2庫基礎函式的詳解
今天我們來學習一個最簡單的程式,即從檔案讀取影象並且建立視窗顯示該影象。
目錄
【imread】影象讀取
【namedWindow】建立window視窗
【imshow】影象顯示
【imwrite】影象寫入檔案
【waitKey】等待按鍵按下
前言
在說正文之前先簡單介紹一下Mat類。Mat類是opencv2.0的主流影象型別,在之前opencv1.0使用的Iplimage*型別,Iplimage*是C語言介面型別,使用Iplimage*時需要考慮到關閉視窗時圖形記憶體的釋放問題。而使用Mat則在一定程度上不需要手動管理記憶體,視窗關閉時會自動釋放影象記憶體。
以下兩點這是我在執行程式時遇到的問題,當然如果大家沒有碰到的話就可以直接無視了。
第一點是關於waitKey()函式的,在學習影象顯示之前我先寫了一個waitKey()等待按鍵按下退出的程式。
1 int main() 2 { 3 int c; 4 while (1) 5 { 6 c = waitKey(0); 7 if (c == 27||char(c) == 'q'|| char(c) == 'Q')//按下Q鍵或者ESC鍵退出程式 8 break; 9 } 10 return 0; 11 }
發現這個程式無論我怎麼按按鍵都沒有用。一通百度之後終於發現在waitKey()函式的說明文件中有這麼一段注意事項:
翻譯過來就是waitKey()函式只有存在一個或一個以上highGUI視窗並且該視窗處於啟用狀態時才有效。於是我修改了以上程式碼如下:
1 int main() 2 { 3 int c; 4 Mat img1 = imread("1.jpg"); 5 namedWindow("影象顯示"); 6 while (1) 7 { 8 imshow("影象顯示", img1);//顯示影象 9 c = waitKey(0); 10 if (c == 27||char(c) == 'q'|| char(c) == 'Q')//按下Q鍵或者ESC鍵退出程式 11 break; 12 } 13 return 0; 14 }
測試之後發現還是不可以,於是博主又是一通折騰,將我建立的視窗移一下位置,發現我建立的視窗竟然有兩個:
無論怎麼點前面帶影象的視窗都沒有把視窗啟用,只有點後面那個不帶影象的才算選擇視窗,然後按鍵才有效。到這裡已經測試實現了waitKey()函式的作用。但是有強迫症的博主當然不能容忍有兩個同名視窗。於是又是一通百度。發現了兩個解決發法。親測都可用:
1.之前博主是在debug模式下執行的,調到release模式下就可以。但是都說了博主有強迫症怎麼就想在debug模式下使用,所以博主用的是第二這個方法。
2.在配置VS環境的時候,我們按照網上大部分的教程(包括博主自己轉載的教程),在配置附加依賴項的時候將debug版本與release版本的都添加了,所以會出現上面的問題,把debug下配置的不帶d的lib刪掉就可以了。需要注意的是,如果勾選的從父項繼承,而父項裡面有不帶d的lib時,上述問題還是會出現。博主取消了勾選父項繼承,不知道以後會不會有問題。
正文
【imread】影象讀取
Mat imread( const String& filename, int flags = IMREAD_COLOR );
第一個引數const string& filename:要讀取的檔名稱。需要注意的是這裡給的圖片名稱是帶有後綴的,並且字尾需要與檔案字尾一致。這個檔名稱可以是圖片的絕對路徑(F:\\2.jpg或F:/2.jpg)也可以是相對路徑。當給相對路徑時,必須將該圖片放到工程目錄與.cpp檔案統一目錄下。圖片格式可以是一下型別之一:
- Windows bitmaps - \*.bmp, \*.dib (always supported) - JPEG files - \*.jpeg, \*.jpg, \*.jpe (see the *Notes* section) - JPEG 2000 files - \*.jp2 (see the *Notes* section) - Portable Network Graphics - \*.png (see the *Notes* section) - WebP - \*.webp (see the *Notes* section) - Portable image format - \*.pbm, \*.pgm, \*.ppm \*.pxm, \*.pnm (always supported) - Sun rasters - \*.sr, \*.ras (always supported) - TIFF files - \*.tiff, \*.tif (see the *Notes* section) - OpenEXR Image files - \*.exr (see the *Notes* section) - Radiance HDR - \*.hdr, \*.pic (always supported) - Raster and Vector geospatial data supported by Gdal (see the *Notes* section)
第二個引數int flags:讀取的圖片格式。圖片格式可以是imageMode列舉:
IMREAD_UNCHANGED = -1, //讀取原圖 IMREAD_GRAYSCALE = 0, //灰度影象 IMREAD_COLOR = 1, //彩色影象 IMREAD_ANYDEPTH = 2, //原圖影象深度 IMREAD_ANYCOLOR = 4, //原圖色彩 IMREAD_LOAD_GDAL = 8, // IMREAD_REDUCED_GRAYSCALE_2 = 16, // IMREAD_REDUCED_COLOR_2 = 17, // IMREAD_REDUCED_GRAYSCALE_4 = 32, // IMREAD_REDUCED_COLOR_4 = 33, // IMREAD_REDUCED_GRAYSCALE_8 = 64, // IMREAD_REDUCED_COLOR_8 = 65, // IMREAD_IGNORE_ORIENTATION = 128 //
【namedWindow】建立window視窗
void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);
第一個引數const string& winname:要建立的視窗名稱。視窗名稱是視窗的唯一標識,如果要建立的視窗名稱已經存在,則該函式不執行任何操作。
第二個引數int flags:視窗屬性。支援WindowFlags列舉:
WINDOW_NORMAL = 0x00000000, //使用者可任意調整視窗大小(無限制) WINDOW_AUTOSIZE = 0x00000001, //根據影象自動調整視窗大小,使用者不可調節 WINDOW_OPENGL = 0x00001000, // WINDOW_FULLSCREEN = 1, //全屏 WINDOW_FREERATIO = 0x00000100, //最大化 WINDOW_KEEPRATIO = 0x00000000, //保持原圖比例 WINDOW_GUI_EXPANDED=0x00000000, // WINDOW_GUI_NORMAL = 0x00000010, //
【imshow】影象顯示
void imshow(const String& winname, InputArray mat);
第一個引數const string& winname:用於顯示圖片的視窗。
第一個引數InputArray mat:要顯示的影象資料。
【imwrite】影象寫入檔案
bool imwrite( const String& filename, InputArray img, const std::vector<int>& params = std::vector<int>());
第一個引數const string& filename:檔名稱。支援的檔案型別與imread相同。
第二個引數InputArray img:影象資料。
第三個引數params:影象儲存的引數,可以不填。
【waitKey】等待按鍵按下
int waitKey(int delay = 0);
等待按鍵按下。括號內參數為延時時間,單位是毫秒ms,有預設引數0,當引數為0時表示一直等待按鍵按下。需要說明的是waitKey()函式只有在至少有一個window視窗並且視窗處於啟用作態時才有效。
例項
1 //************標頭檔案包含************* 2 #include "stdafx.h" 3 #include<iostream> 4 #include<opencv.hpp>//包含opencv的標頭檔案 5 //*********************************** 6 7 8 //************名稱空間*************** 9 using namespace cv;//使用opencv名稱空間 10 using namespace std; 11 //*********************************** 12 13 14 //************主函式***************** 15 int main() 16 { 17 int c; 18 Mat img1 = imread("1.jpg"); 19 20 namedWindow("影象顯示");//建立視窗 21 22 while (1) 23 { 24 imshow("影象顯示", img1);//顯示影象 25 26 c = waitKey(0);//等待按鍵按下 27 if (c == 27||char(c) == 'q'|| char(c) == 'Q')//按下Q鍵或者ESC鍵退出程式 28 break; 29 } 30 31 return 0; 32 }
執行之後的顯示結果: