本文內容摘自於仕琪老師寫的《opencv入門教程》
示例程序如最下面所示:
在讀取矩陣元素時,以及獲取矩陣某行的地址時,需要指定數據類型。這樣首先需要不停地寫“<uchar>”,讓人感覺很繁瑣,在繁瑣和煩躁中容易犯錯,如下面代碼中的錯誤,用 at()獲取矩陣元素時錯誤的使用了 double 類型。這種錯誤不是語法錯誤,因此在編譯時編譯器不會提醒。在程序運行時, at()函數獲取到的不是期望的(i,j)位置處的元素,數據已經越界,但是運行時也未必會報錯。這樣的錯誤使得你的程序忽而看上去正常,忽而彈出“段錯誤”,特別是在代碼規模很大時,難以查錯。
如果使用 Mat_類,那麼就可以在變量聲明時確定元素的類型, 訪問元素時不再需要指定元素類型,即使得代碼簡潔,又減少了出錯的可能性。上面代碼可以用 Mat_實現,實現代碼如下面例程裏的第二個雙重 for 循環。
#include <iostream>
#include "opencv2/opencv.hpp"#include<stdio.h>
using namespace std;
using namespace cv;
int main(int argc,char* argv[])
{
Mat M(600,800,CV_8UC1);
for(int i=0;i<M.rows;++i){
//獲取指針時需要指定類型
uchar *p=M.ptr<uchar>(i);
for(int j=0;j<M.cols;++j){
double d1=(double)((i+j)%255);
//用at讀像素時,需要指定類型
M.at<uchar>(i,j)=d1;
double d2=M.at<uchar>(i,j);
}
}
//在變量聲明時,指定矩陣元素類型
Mat_<uchar> M1=(Mat_<uchar>&)M;
for(int i=0;i<M1.rows;++i)
{
//不需要指定元素類型,語言簡潔
uchar *p=M1.ptr(i);
for(int j=0;j<M1.cols;++j){
double d1=(double)((i+j)%255);
//直接使用matlab風格的矩陣元素讀寫,簡潔
M1(i,j)=d1;
double d2=M1(i,j);
}
}
return 0;
}