前言
早期的 OpenCV
中,使用 IplImage
和 CvMat
數據結構來表示圖像。
IplImage和 CvMat
都是 C
語言的結構。 使用這兩個結構的問題是內存需要手動管理,開發者必須清楚的知道何時需要申請內存,何時需要釋放內存。這個開發者帶來了一定的負擔,開發者應該將更多精力用於算法設計,因此在新版本的
OpenCV
中引入了 Mat
類。
1.關於mat類
1.1 Mat類成員:
屬性:
Int flags;
Int dims;維數
Int rows,cols; 行列數
Uchar* data;數據指針
Int* refconut;引用次數
常用構造函數:
(1)只創建不初始化
Mat M(3,2,CV_8UC1);
(2)新創建Mat對象,並初始化
Mat M(3,2,CV_8UC3,Scalar(0,0,255));
Mat M(Sizesize,int type);
Mat M(Sizesize,int type,const Scalar& s);
(3)利用已有的對象(不會複製數據)
Mat::Mat(constMat& m)
Mat::Mat(constMat& m, const Rect& roi)
注:如果你需要更多的通道數,需要用宏CV_8UC(n),例如:
Mat M(3,2, CV_8UC(5));//創建行數爲 3,列數爲 2,通道數爲 5 的圖像
(4)用Mat::create()創建
(5)MATLAB風格創建特殊矩陣
Mat::zeros(rows,cols,type);
Mat::ones(rows,cols,type);Mat::eye(rows,cols,type);
注:Mat等類重載了<<運算符,cout<<M<<endl,打印矩陣元素;
1.2 Mat表達式
Mat a(),b(),c();
int k;
a=b+c;
c=a*k;
a.mul(b) 對應元素相乘
a/b,k/a對應元素除
a*b 矩陣乘
a.t() 轉置
a.inv() 求逆
1.3.Mat_類
template<typename_Tp> class Mat_ : public Mat
{
public:
//只定義了幾個方法
//沒有定義新的屬性
};
1.4 Mat內存管理
使用引用計數機制,當引用爲0時,自動釋放內存。
2.矩陣元素表達(多通道)
使用小向量VecNX,N表示通道數,
X = b(byte)
s(short)
i(int)
f(float)
d(double)
3.訪問矩陣元素
3.1 at()
Mat M();
M.at<uchar>(i,j)
3.2 迭代器
3.3 指針
Matm(3,2,CV_8UC1);//sigle channel
For(inti=0;i<m.rows;i++)
{
Uchar* p = m.ptr<uchar>(i); //獲取行指針
For(j=0;j<m.cols,;j++)
{
P[j] = xxx;
}
}
注意:這裏的rows和cols的單位都是以矩陣元素爲單位的
Matm(3,2,CV_8UC3);//three channels
For(int=0;i<m.rows;i++)
{
Vec3b* pv = m.ptr<Vec3b>(i);
For(int j=0;j<cols;j++)
{
Pv[j][0] = aaa;
Pv[j][2] = aaa;
Pv[j][3] = aaa;
}
}
注意:Data* p; p[i]是以Data數據項爲單位計數的。
4.IplImage,CvMat與Mat轉換
這塊用到再補充。
5.讀寫圖像
Mat imread(conststring& filename,int flags=1);
Flags>0 強制轉換成3channel
Flags=0強制轉換成1channel
Flags<0 不轉換
bool imwrite(conststring& filename,
InputArray image,
Vector<int>& params);
Vector<int>¶ms 與圖像格式有關的參數。
注意:並不是所用類型的Mat都能夠被保存爲圖像。有的需要進行轉換纔可以。
6.讀取視頻(VideoCapture)
(1)創建VideoCapture對象
VideoCapture cap(“xxx.avi”);
(2)加載一幀圖像到內存
Mat frame;
cap>>frame;
(3)顯示圖像
imshow(“windowName”,frame);