1. 程式人生 > >opencv-常用小知識

opencv-常用小知識

cv::Mat定義,初始化和賦值

  • 第一種:cv::Mat M(height,width, )
cv::Mat mat(row_num, col_num, CV_64F3, cv::Scalar(0))
  • 第二種: cv::Mat M = cv::Mat(height,width, ,data)
float K[3][3] = {fc[0], 0, cc[0], 0, fc[1], cc[1], 0, 0, 1};    //攝像機內參數矩陣K
cv::Mat mK = cv::Mat(3,3,CV_32FC1,K);    //內參數K Mat型別變數
  • 第三種:zeros(),ones(),eyes()的初始化
cv::Mat M = cv::Mat::eye(height,width,<Type>)
cv::Mat M = cv::Mat::ones(height,width,<Type>)
cv::Mat M = cv::Mat::zeros(height,width,<Type>)
  • 第四種:對於小矩陣給定數值的賦值方法:
cv::Mat M = (cv::Mat_<Type>(height,width) << 0,-1,0,-1,5,-1,0,-1,0)

訪問Mat元素的方法

方式1: at (i, j)訪問

這種方式在Debug模式下的訪問速度是最慢的,但是在Release模式下的訪問速度也是相當快的,和其他方式相近。

  • 單通道遍歷
int ROWS = 100; // height
int COLS = 200; // width
Mat img1(ROWS , COLS , CV_32FC1);  
  
for (int i=0; i<ROWS ; i++)  
{  
    for (int j=0; j<COLS ; j++)  
    {  
        img1.at<float>(i,j) = 3.2f;  
    }  
}
  • 多通道遍歷
int ROWS = 100; // height
int COLS = 200; // width
Mat img1(ROWS , COLS , CV_8UC3);  
  
for (int i=0; i<ROWS ; i++)  
{  
    for (int j=0; j<COLS ; j++)  
    {  
       img1.at<cv::Vec3b>(i,j)[0]= 3.2f;  // B 通道
       img1.at<cv::Vec3b>(i,j)[1]= 3.2f;  // G 通道
       img1.at<cv::Vec3b>(i,j)[2]= 3.2f;  // R 通道
    }  
}  

注:這種方式會判斷溢位, 不會出現指標越位問題。

方式2: ptr (i) [j] 方式

int ROWS = 100; // height
int COLS = 200; // width
Mat img5(ROWS , COLS , CV_32FC1); 
 
for (int i=0; i<ROWS ; i++)   
{   
    const float* pData1=img5.ptr<float>(i);  
    for (int j=0; j<COLS ; j++)   
    {   
        pData1[j] = 3.2f;   
    }   
}  
                         

另外,通過判斷資料記憶體區域為連續,可以將矩陣當做一個長向量進行訪問(下面改用首地址用data獲取,但是data預設是 uchar* 型別,需要進行強制轉換):

if (M.isContinuous())        // 一般手動分配或者深複製的矩陣,都是連續的。
{
    //const double*Mi = M.ptr<double>(0);                   32us
    const double*Mi = (double *)M.data;                     32us
    for (int j = 0; j < M.cols*M.rows; j++)
        sum += Mi[j];
}                       

參考

opencv Mat資料的三種標準訪問方式 - Zack888 - 部落格園
OpenCv2 學習筆記(6) Mat元素訪問和效率比較 - wanggao_1990的專欄 - CSDN部落格