圖像的載入和顯示
在OpenCV2之后的版本中笑旺,圖像載入的顯示只需要3句代碼文留。它們分別對應(yīng)3個函數(shù):imread(),nameWindow(),imshow()好唯。接下來會依次解釋這三個函數(shù)。
imread函數(shù)
imread:聲明如下
Mat imread(const string& filename, int flags=1 );
- 第一個參數(shù)const string& filename燥翅,這里填的是圖片的路徑名骑篙。在Windows系統(tǒng)下imread函數(shù)支持一下類型的圖像載入:
Windows位圖 - *.bmp, *.dib
JPEG文件 - *.jpeg, *.jpg, *.jpe
JPEG 2000文件- *.jp2
PNG圖片 - *.png
便攜文件格式- *.pbm, *.pgm, *.ppm
Sun rasters光柵文件 - *.sr, *.ras
TIFF 文件 - *.tiff, *.tif
- 第二個參數(shù)int flags,它指定一個加載圖像的顏色類型权旷√骝龋可以看到它自帶缺省值1.所以有時候這個參數(shù)在調(diào)用時我們可以忽略,在看了下面的講解之后拄氯,我們就會發(fā)現(xiàn)躲查,如果在調(diào)用時忽略這個參數(shù),就表示載入三通道的彩色圖像译柏×椭螅可以在OpenCV中標(biāo)識圖像格式的枚舉體中取值。通過轉(zhuǎn)到定義鄙麦,我們可以在higui_c.h中發(fā)現(xiàn)這個枚舉的定義是這樣的:
enum
{
/* 8bit, color or not */
CV_LOAD_IMAGE_UNCHANGED =-1,
/* 8bit, gray */
CV_LOAD_IMAGE_GRAYSCALE =0,
/* ?, color */
CV_LOAD_IMAGE_COLOR =1,
/* any depth, ? */
CV_LOAD_IMAGE_ANYDEPTH =2,
/* ?, any color */
CV_LOAD_IMAGE_ANYCOLOR =4
};
對應(yīng)的解釋:
CV_LOAD_IMAGE_UNCHANGED 已被廢置典唇,忽略
CV_LOAD_IMAGE_GRAYSCALE 始終將載入的圖像轉(zhuǎn)換成8位灰度圖
CV_LOAD_IMAGE_COLOR 默認(rèn)值,始終將載入的圖像轉(zhuǎn)換成彩色圖像
CV_LOAD_IMAGE_ANYDEPTH 若載入圖像的深度為16位或者32位胯府,就返回對應(yīng)深度的圖像介衔,否則,就轉(zhuǎn)換為8位圖像再返回骂因。
CV_LOAD_IMAGE_ANYCOLOR 載入無損的源圖像
如果輸入有沖突表示炎咖,將采用較小數(shù)值,例如:
CV_LOAD_IMAGE_COLOR | CV_LOAD_IMAGE_ANYCOLOR
當(dāng)然你也可以這么輸入flags值:
flags>0寒波,三通道彩色圖
flags=0乘盼,灰度圖
flags<0,包含Alpha通道的圖像
下面是幾個例子:
Mat image1=imread("test.jpg",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);//載入最真實的圖像
Mat image2=imread("test.jpg",199);//載入3通道的彩色圖像
Mat image3=imread("test.jpg");//載入3通道的彩色圖像 ,和上一條代碼一樣
Mat gray=imread("test.jpg",0);//載入灰度圖
nameWindows函數(shù)
nameWindows函數(shù)聲明如下:
void namedWindow(const string& winname,int flags=WINDOW_AUTOSIZE );
- 第一個參數(shù)const string& winname俄烁,輸入窗口的名字
- 第二個參數(shù)int flags绸栅,窗口的標(biāo)識,可以填以下值:
WINDOW_AUTOSIZE 默認(rèn)值页屠,用戶不能改變窗口大小
WINDOW_NORMAL 用戶可以改變窗口大小
WINDOW_OPENGL 如果設(shè)置了這個值的話粹胯,窗口創(chuàng)建的時候便會支持OpenGL蓖柔。
我們可以調(diào)用destroyWindow()或者destroyAllWindows()函數(shù)來關(guān)閉窗口,并取消之前分配的與窗口相關(guān)的所有內(nèi)存空間矛双。
但話是這樣說渊抽,其實對于代碼量不大的簡單小程序來說,我們完全沒有必要手動調(diào)用上述的destroyWindow()或者destroyAllWindows()函數(shù)议忽,因為在退出時懒闷,所有的資源和應(yīng)用程序的窗口會被操作系統(tǒng)會自動關(guān)閉。
nameWindow函數(shù)一般配合imshow栈幸、waitKey函數(shù)一起使用愤估,是一套組合拳。下面會有介紹速址。
imshow函數(shù)
imshow函數(shù)聲明如下:
void imshow(const string& winname, InputArray mat);
- 第一個參數(shù)const string& winname玩焰,指定要顯示的窗口名稱
- 第二個參數(shù)InputArray mat,要顯示的圖片
imshow 函數(shù)用于在指定的窗口中顯示圖像芍锚。如果窗口是用CV_WINDOW_AUTOSIZE(默認(rèn)值)標(biāo)志創(chuàng)建的昔园,那么顯示圖像原始大小。否則并炮,將圖像進(jìn)行縮放以適合窗口默刚。而imshow 函數(shù)縮放圖像,取決于圖像的深度:
- 如果載入的圖像是8位無符號類型(8-bit unsigned)逃魄,就顯示圖像本來的樣子荤西。
- 如果圖像是16位無符號類型(16-bit unsigned)或32位整型(32-bit integer),便用像素值除以256伍俘。也就是說邪锌,值的范圍是[0,255 x 256]映射到[0,255]。
-如果圖像是32位浮點型(32-bit floating-point)癌瘾,像素值便要乘以255觅丰。也就是說,該值的范圍是[0,1]映射到[0,255]妨退。
在顯示載入的圖像時一般是這么做的:
Mat src = imread(“test.jpg”);
nameWindows(“示例”);
imshow(“示例”,src);
waitKey(0);
如果不加waitKey函數(shù)則會看到窗口一閃即逝妇萄,waitKey函數(shù)的作用是讓窗口暫停,參數(shù)為0時表示如果沒有操作則永久展示窗口碧注。輸入數(shù)字表示暫停毫秒數(shù),若想暫停1秒則是waitKey(1000)糖赔。如果waitKey函數(shù)之前有很多nameWindow + imshow的組合萍丐,則會顯示之前的所有的窗口并暫停。waitKey函數(shù)還用于控制視頻顯示的幀數(shù)放典。
圖像的寫入
imwrite函數(shù)
函數(shù)聲明:
bool imwrite(const string& filename,InputArray img, const vector<int>& params=vector<int>() );
- 第一個參數(shù)逝变,const string&類型的filename基茵,填需要寫入文件的路徑名就行了,帶上后綴壳影,比如相對路徑“tmp/123.jpg”或者絕對路徑“F:/MicrosoftVisualStudio2013/workspace/test/test/tmp/123.jpg”拱层。
- 第二個參數(shù),InputArray類型的img宴咧,一般填一個Mat類型的圖像數(shù)據(jù)就行了根灯。
- 第三個參數(shù),const vector<int>&類型的params掺栅,表示為特定格式保存的參數(shù)編碼烙肺,它有默認(rèn)值vector<int>(),所以一般情況下不需要填寫氧卧。而如果要填寫的話桃笙,有下面這些需要了解的地方:
對于JPEG格式的圖片,這個參數(shù)表示從0到100的圖片質(zhì)量(CV_IMWRITE_JPEG_QUALITY)沙绝,默認(rèn)值是95.
對于PNG格式的圖片搏明,這個參數(shù)表示壓縮級別(CV_IMWRITE_PNG_COMPRESSION)從0到9。較高的值意味著更小的尺寸和更長的壓縮時間闪檬,而默認(rèn)值是3星著。
對于PPM,PGM谬以,或PBM格式的圖片强饮,這個參數(shù)表示一個二進(jìn)制格式標(biāo)志(CV_IMWRITE_PXM_BINARY),取值為0或1为黎,而默認(rèn)值是1邮丰。
綜合示例
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace cv;
int main(){
// 讀取一張圖片
Mat img1 = imread("街景1.jpg");
// 創(chuàng)建一個名為 "街景1"窗口,"WINDOW_NORMAL"表示可改變大小,數(shù)字2也可以
namedWindow("街景1", WINDOW_NORMAL);
// 在窗口中顯示原畫
imshow("街景1", img1);
Mat img2 = imread("街景2.jpg");
// 創(chuàng)建一個名為 "街景2"窗口铭乾,不能改變窗口大小
namedWindow("街景2");
imshow("街景2", img2);
// 點擊“X”后窗關(guān)閉
waitKey(0);
//將img2寫入街景2 - 副本.jpg
imwrite("街景2 - 副本.jpg", img2);
return 0;
}
可以看到“街景1”窗口已經(jīng)被我殘忍的拉長了剪廉。
把兩個窗口“X”掉,去到工作目錄里可以看到多了“街景2 – 副本.jpg”這一文件炕檩。內(nèi)容和“街景2.jpg”一樣斗蒋。