一: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 ?
- #include <opencv2\core\core.hpp>
- #include <opencv2\highgui\highgui.hpp>
- #include <opencv2\imgproc\imgproc.hpp>
- #include <iostream>
- using namespace std;
- using namespace cv;
- int main()
- {
- Mat image = imread("F:\\tongtong.jpg", 1); //讀取圖檔
- if(!image.data) // data指向已配置設定記憶體塊的指針
- {
- cout << "fail to load image" << endl;
- }
- cout << "image size: " << image.size().height << "," << image.size().width << endl; //size()傳回的是一個結構體
- namedWindow("show");
- imshow("show", image); // 顯示圖檔
- imwrite("F:\\tongtong2.jpg", image);
- <span style="white-space:pre"> </span>Mat result;
- flip(image,result, 0);
- namedWindow("result",0);
- imshow("result", result);
- waitKey(0);
- return 0;
- }
(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)結果:
三:深淺拷貝
(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, 歡迎交流