申明:以下的小技巧,均為OpenCV2.4.2下驗證過的,但並不保證其它版本依然奏效
(1)利用數組來構建cv::Mat
示例代碼如下所示:
[cpp]
void ArrayToMat()
{
double m[3][3];
for (int i=0; i<3; i++)
{
for (int j=0; j<3; j++)
{
m[i][j] = i+j;
cout<<m[i][j]<<" ";
}
cout<<endl;
}
cout<<"****************************************"<<endl;
Mat M = Mat(3, 3, CV_64F, m);
double tempVal = 0.0;
for (int i=0; i<3; i++)
{
for (int j=0; j<3; j++)
{
tempVal = M.at<double>(i,j);
cout<<tempVal<<" ";
}
cout<<endl;
}
}
不出意外的話,執行結果應該如下所示:
(2) IplImage*跟cv::Mat之間的互相轉換
示例代碼:
[cpp]
void IplImageToMat()
{
IplImage* pImg = cvLoadImage("c:/test.jpg");
if (!pImg)
{
cout<<"pImg load error"<<endl;
system("pause");
exit(-1);
}
cvNamedWindow("pImg", 0);
cvNamedWindow("mtx", 0);
Mat mtx(pImg);
cvShowImage("pImg", pImg);
imshow("mtx", mtx);
cvWaitKey(0);
cvReleaseImage(&pImg);
}
筆者任意加載了電腦上一副圖片,結果如下所示:
提醒,這裡的格式轉換並不申請新的內存,而僅僅是改變數據結構而已
(3)Mat轉換為IplImge
示例代碼:
[cpp]
void MatToIplImage()
{
Mat m = imread("c:/test.jpg");
if (m.empty())
{
cout<<"mat load error"<<endl;
system("pause");
exit(-1);
}
IplImage img1 = IplImage(m);
IplImage img2 = m;
cvNamedWindow("img1", 0);
cvNamedWindow("img2", 0);
cvShowImage("img1", &img1);
cvShowImage("img2", &img2);
cvWaitKey(0);
}
筆者任意加載一張圖片,上述代碼的執行結果為:
(4)訪問二維數據(cv::Mat)最高效的方式是先得到該二維數據的每一行的指針,然後利用下標運算符逐列訪問
示例代碼:
[cpp]
void MatAccess()
{
double m[3][3];
for (int i=0; i<3; i++)
{
for (int j=0; j<3; j++)
{
m[i][j] = i+j;
cout<<m[i][j]<<" ";
}
cout<<endl;
}
cout<<"****************************************"<<endl;
Mat M = Mat(3, 3, CV_64F, m);
double sum = 0;
int rows = M.rows;
int cols = M.cols;
for (int i=0; i<rows; i++)
{
const double* Mi = M.ptr<double>(i);
for (int j=0; j<cols; j++)
{
sum += Mi[j];
}
}
cout<<"sum: "<<sum<<endl;
}
上面的代碼執行結果為:
(5)cv::Mat支持STL中的迭代器功能
示例代碼:
[cpp]
void MatAccess()
{
double m[3][3];
for (int i=0; i<3; i++)
{
for (int j=0; j<3; j++)
{
m[i][j] = i+j;
cout<<m[i][j]<<" ";
}
cout<<endl;
}
cout<<"****************************************"<<endl;
Mat M = Mat(3, 3, CV_64F, m);
double sum = 0;
int rows = M.rows;
int cols = M.cols;
for (int i=0; i<rows; i++)
{
const double* Mi = M.ptr<double>(i);
for (int j=0; j<cols; j++)
{
sum += Mi[j];
}
}
cout<<"sum: "<<sum<<endl;
sum = 0;
MatConstIterator_<double> it = M.begin<double>();
MatConstIterator_<double> itEnd = M.end<double>();
for (;it!=itEnd; it++)
{
sum += *it;
}
cout<<"sum: "<<sum<<endl;
}
運行結果:
(6) satureat_cast : openCV中用於數據“飽和”判斷
示例:
[cpp]
void Saturate_castTest()
{
int r = 300;
uchar t = saturate_cast<uchar>(r);
cout<<int(t)<<endl;
}
結果:
(7)獲取函數執行時間
getTickCount()和getTickFrequency()結合起來可以用來計算函數執行時間,尤其是很小的代碼片段的執行時間
舉例:
[cpp]
void GetFuncTime()
{ www.2cto.com
double exec_time = (double)getTickCount();
for (int i=0; i<10; i++)
{
;
}
exec_time = ((double)getTickCount() - exec_time)*1000./getTickFrequency();
cout<<exec_time<<endl;
}
上面的代碼,重點在於for循環,且,該循環中什麼也不處理;用一般的時間函數很難計算出該代碼片段的執行時間,但利用getTickCount()和getTickFrequency()就很容易。筆者電腦上的結果是: