1. 程式人生 > >OpenCV影象載入,顯示,儲存,融合

OpenCV影象載入,顯示,儲存,融合

一、OpenCV的名稱空間

   OpenCV中的C++類和函式都是定義在名稱空間cv之內的,在寫OpenCV程式時,以下三句為標配:

#include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
 
using namespace cv;

二、Mat型別

Mat型別作為OpenCV2新紀元的重要代表“人物”,是對應於OpenCV1.0時代的IplImage的主要用來存放影象的資料結構。

 Mat myMat= imread("dota.jpg");

表示從工程目錄下把一幅名為dota.jpg的jpg型別的影象載入到Mat型別的myMat中。

三、影象載入與顯示

1.imread函式

Mat imread(const string& filename, intflags=1 );

第一個引數,const string&型別的filename,填我們需要載入的圖片路徑名。在Windows作業系統下,OpenCV的imread函式支援如下型別的影象載入:

  • Windows點陣圖 - *.bmp, *.dib
  • JPEG檔案 - *.jpeg,*.jpg, *.jpe
  • JPEG 2000檔案- *.jp2PNG圖片 - *.png
  • 便攜檔案格式- *.pbm, *.pgm, *.ppmSun rasters
  • 光柵檔案 - *.sr, *.ras
  • TIFF 檔案 - *.tiff, *.tif

第二個引數,int型別的flags,為載入標識,它指定一個載入影象的顏色型別。

Mat image0=imread("dota.jpg",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);//載入最真實的影象
Mat image1=imread("dota.jpg",0);//載入灰度圖
Mat image2=imread("dota.jpg",199);//載入3通道的彩色影象
Mat logo=imread("dota_logo.jpg");//載入3通道的彩色影象

2.namedWindow函式

namedWindow函式,用於建立一個視窗。

void namedWindow(const string& winname,int flags=WINDOW_AUTOSIZE ); 

第一個引數,const string&型的name,即填被用作視窗的識別符號的視窗名稱。  

第二個引數,int 型別的flags ,視窗的標識,可以填如下的值:

          WINDOW_NORMAL設定了這個值,使用者便可以改變視窗的大小(沒有限制)

          WINDOW_AUTOSIZE如果設定了這個值,視窗大小會自動調整以適應所顯示的影象,並且不能手動改變視窗大小。

          WINDOW_OPENGL 如果設定了這個值的話,視窗建立的時候便會支援OpenGL

函式剖析:首先需要注意的是,它有預設值WINDOW_AUTOSIZE,所以,一般情況下,這個函式填一個變數就行了。

namedWindow函式的作用是,通過指定的名字,建立一個可以作為影象和進度條的容器視窗。如果具有相同名稱的視窗已經存在,則函式不做任何事情。

我們可以呼叫destroyWindow()或者destroyAllWindows()函式來關閉視窗,並取消之前分配的與視窗相關的所有記憶體空間。

但話是這樣說,其實對於程式碼量不大的簡單小程式來說,我們完全沒有必要手動呼叫上述的destroyWindow()或者destroyAllWindows()函式,因為在退出時,所有的資源和應用程式的視窗會被作業系統會自動關閉。

3.imshow函式

在指定的視窗中顯示一幅影象。

void imshow(const string& winname, InputArray mat);

第一個引數,const string&型別的winname,填需要顯示的視窗標識名稱。

第二個引數,InputArray 型別的mat,填需要顯示的影象。

imshow 函式詳解:

imshow 函式用於在指定的視窗中顯示影象。如果視窗是用CV_WINDOW_AUTOSIZE(預設值)標誌建立的,那麼顯示影象原始大小。否則,將影象進行縮放以適合視窗。而imshow 函式縮放影象,取決於影象的深度:

       如果載入的影象是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]。

還有一點,若視窗建立(namedWindow函式)的時候,如果設定了支援OpenGL(WINDOW_OPENGL ),那麼imshow還支援ogl::Buffer ,ogl::Texture2D以及gpu::GpuMat作為輸入。

四、輸出影象到檔案——imwrite函式

在OpenCV中,輸出影象到檔案,我們一般都用imwrite函式,它的宣告如下:

bool imwrite(const string& filename,InputArray img, const vector<int>& params=vector<int>() );

第一個引數,const string&型別的filename,填需要寫入的檔名就行了,帶上字尾,比如,“123.jpg”這樣。 

第二個引數,InputArray型別的img,一般填一個Mat型別的影象資料就行了。

第三個引數,const vector<int>&型別的params,表示為特定格式儲存的引數編碼,它有預設值vector<int>(),所以一般情況下不需要填寫。而如果要填寫的話,有下面這些需要了解的地方:

            對於JPEG格式的圖片,這個引數表示從0到100的圖片質量(CV_IMWRITE_JPEG_QUALITY),預設值是95.

            對於PNG格式的圖片,這個引數表示壓縮級別(CV_IMWRITE_PNG_COMPRESSION)從0到9。較高的值意味著更小的尺寸和更長的壓縮時間,而預設值是3。

            對於PPM,PGM,或PBM格式的圖片,這個引數表示一個二進位制格式標誌(CV_IMWRITE_PXM_BINARY),取值為0或1,而預設值是1。

函式解析:

imwrite函式用於將影象儲存到指定的檔案。影象格式是基於副檔名的,可儲存的副檔名和imread中可以讀取的影象副檔名一樣。

五、一個綜合示例

最後是一個綜合示例,載入影象,進行簡單影象混合,顯示影象,並且輸出混合後的影象到jpg。

 
 
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
 
using namespace cv;
 
 
int main( )
{
//載入圖片
Mat image= imread("dota.jpg",199);
Mat logo= imread("dota_logo.jpg");
 
//載入後先顯示
namedWindow("【2】原畫圖");
imshow("【2】原畫圖",image);
 
namedWindow("【3】logo圖");
imshow("【3】logo圖",logo);
 
//定義一個Mat型別,用於存放,影象的ROI
Mat imageROI;
//方法一
imageROI=image(Rect(800,350,logo.cols,logo.rows));
//方法二
//imageROI=image(Range(350,350+logo.rows),Range(800,800+logo.cols));
 
//將logo加到原圖上
addWeighted(imageROI,0.5,logo,0.3,0.,imageROI);
 
//顯示結果
namedWindow("【4】原畫+logo圖");
imshow("【4】原畫+logo圖",image);
 
//     描述:將一個Mat影象輸出到影象檔案
//-----------------------------------------------------------------------------------------------
//輸出一張jpg圖片到工程目錄下
imwrite("我喜歡打dota2 by淺墨.jpg",image);
 
waitKey(6000);//視窗在6000秒後自動關閉
 
return 0;
}

關於影象混合的函式的初步理解:

imageROI=image(Rect(int_x,int_y,int_width,int_height);

   影象的感興趣區域,imageROI的資料與源影象image共享儲存區,所以此後在imageROI上的操作也會作用在源影象image上。

    注:int_x,int_y為待混合影象左上角在原影象中的座標。

           兩張影象混合時,影象型別應相同

addWeighted(imageROI,0.5,logo,0.3,0.,imageROI);

//陣列相加函式,imageROI為原陣列,0.8為該陣列權值,logo為另一個原陣列,0.2為該陣列權重,0為新增常數項,imageROI為輸出目標陣列,函式輸出結果為:imageROI=imageROI*0.5+logo*0.3+0