天天看點

Opencv2系列學習筆記1(圖像的基本操作)

一:Opencv2與opencv1的差別:

    Opencv1.0版本于2006年面世,主要基于C語言。2009年釋出opencv2,主要基于C++。此時opencv庫被劃分成多個子產品,這些子產品被編譯成庫檔案後,位于lib檔案夾中。主要有以下子產品(版本1的結構見我的這篇blog:http://blog.csdn.net/lu597203933/article/details/13614377):

Opencv_core子產品:包含核心功能,尤其是底層資料結構和算法函數。

Opencv_improc子產品:包含圖像處理函數。

Opencv_highgui子產品:包含讀寫圖像及視訊的函數,以及操作圖形使用者界面函數。

Opencv_features2d子產品:包含興趣點檢測子,描述子以及興趣點比對架構。

Opencv_calib3d子產品:包含相機标定,雙目幾何估計以及立體視覺函數。

Opencv_video子產品:包含運動估算,特征跟蹤以及前景提取函數與類。

Opencv_objdetect子產品:包括物體檢測函數,如臉部和行人檢測。

庫中還包含其它的工具子產品,如機器學習(opencv_ml),計算幾何(opencv_flann),第三方代碼(opencv_contrib)等。這些子產品都對有一個單獨的頭檔案(位于include檔案夾)。推薦的聲明方式如下:

       #include<opencv2\core\core.hpp>

#include<opencv2\highgui\highgui.hpp>

#include<opencv2\imgproc\imgproc.hpp>

而#include "cv.h"這是舊的代碼方式,那是庫還沒有被劃分為子產品。

二:讀取、顯示和儲存圖檔

    (1)代碼:

[cpp]  view plain  copy  print ?

  1. #include <opencv2\core\core.hpp>  
  2. #include <opencv2\highgui\highgui.hpp>  
  3. #include <opencv2\imgproc\imgproc.hpp>  
  4. #include <iostream>  
  5. using namespace std;  
  6. using namespace cv;  
  7. int main()  
  8. {  
  9.     Mat image = imread("F:\\tongtong.jpg", 1);  //讀取圖檔  
  10.     if(!image.data)                  // data指向已配置設定記憶體塊的指針  
  11.     {  
  12.         cout << "fail to load image" << endl;  
  13.     }  
  14.     cout << "image size: " << image.size().height << "," << image.size().width << endl; //size()傳回的是一個結構體  
  15.     namedWindow("show");  
  16.     imshow("show", image);       // 顯示圖檔  
  17.     imwrite("F:\\tongtong2.jpg", image);  
  18. <span style="white-space:pre">  </span>Mat result;  
  19.     flip(image,result, 0);  
  20.     namedWindow("result",0);  
  21.     imshow("result", result);  
  22.     waitKey(0);  
  23.     return 0;     
  24. }  

    (2)Explaination:

<1>opencv2中用于存儲圖像資料為Mat類型,而在opencv1中用IplImage(詳細見我的這篇blog:http://blog.csdn.net/lu597203933/article/details/13957271)。優點在于Mat是一個類,定義的類類型可以自動配置設定和釋放記憶體空間,而IplImage需手動為其配置設定和釋放記憶體空間,當圖像較多時,可能會有偏差,造成記憶體洩露。

<2>image.data是指向已配置設定的記憶體塊的指針,當圖檔沒有加載進來,則為NULL。

<3>image.size()傳回的是一個結構體,實際上包括width和height這兩個成員變量。

<4>flip(image,result,0); //其中正數表示水準反轉,0表示垂直反轉,負數表示既有水準又有垂直反轉。

(3)結果:

Opencv2系列學習筆記1(圖像的基本操作)

三:深淺拷貝

(1)  淺拷貝:

Mat B;

B = image ; // 第一種方式

Mat C(image); // 第二種方式

這兩種方式稱為淺copy,是由于它們有不同的矩陣頭,但是它們共享記憶體空間,即指向一個矩陣。當圖像矩陣發生變化時,兩者相關聯,都會變化。

(2)  深拷貝:

Mat B,C;

B = image.clone();       // 第一種方式

image.copyTo(C); // 第二種方式

深拷貝是真正的copy了一個新的圖像矩陣,此時image,B,C三者互相沒有影響。

四:IplImage裝換為Mat

       IplImage*iplImage = cvLoadImage("F:\\11.jpg",1); 

Mat image2(iplImage,false);

// 其中false為淺拷貝,而true為深拷貝,預設為false。此時注意需要釋放iplImage

當然opencv提供了另外一種指針類,無需手動釋放,但現在已經不用了,可以使用它來封裝IplImage指針:

Ptr<IplImage> iplImage = cvLoadImage("F:\\11.jpg",1); 

作者:小村長  出處:http://blog.csdn.net/lu597203933 歡迎轉載或分享,但請務必聲明文章出處。 (新浪微網誌:小村長zack, 歡迎交流

繼續閱讀