OpenCV學習(4) Mat的基本操作(1)


      圖像在OpenCV中都是通過Mat類來存儲的,Mat可以用來表示N維矩陣,當然用的最多的還是二維矩陣。

      Mat類有兩部分組成:第一部分是頭信息,這些信息主要用來描述矩陣,比如矩陣維數ndims,rows,cols(這兩個成員變量主要用於二維矩陣,用來表示行數和列數),size,sizes, type,step等等;第二部分是data信息,這是一個指針,指向Mat中存儲的數據。

通過下面的代碼,我們創建一個二維矩陣,並打印出矩陣:

//創建一個5*5的2維矩陣,數據類型為8bit的無符號數,數據為3個通道,初始值都為(0,0,255)

cv::Mat M(5,5, CV_8UC3, cv::Scalar(0,0,255));

cout << "M = " << endl << " " << M << endl << endl;

image

 

      這個矩陣的頭信息和數據如下圖所示:

      step表示每一行占據的字節數目,包括padding數據,其中每行中的padding數據有點嚇到我了,我們只有15個uchar而已,沒想到step竟然這么大,而且每次運行程序還是變化的,真正的數據大小是 M.cols*M.elemSize() = 15,我們可以通過函數M.isContinuous()知道當前矩陣是否有padding數據。

     沒有padding數據時候,我們可以把矩陣的data當一維數據處理,數據長度就是rows*cols*elemSize()。

image

下面我看看如何訪問矩陣中的元素,並進行操作:

1. 直接訪問data,簡單快速。

for(i=0; i< M.rows; i++)

{

    for(j=0; j<M.cols*M.elemSize(); j++)

   {

       printf ("%d ", M.data[i*M.cols*M.elemSize() + j]);

   }

   printf("\n");

}

或者用下面的代碼:

uchar* p;

for( i = 0; i < M.rows; ++i)

{

    //得到第i行的指針,等價於 p = M.data + i*M.step

    p = M.ptr<uchar>(i);

    for ( j = 0; j < M.cols; ++j)

    {

      printf (" %d %d %d",p[j*3], p[j*3+1],p[j*3+2]);

     }

    printf("\n");

    或者我們也可以用at的方式得到數組元素,M.at<cv::Vec3b>(i,j)[2]得到元素中的第2個分量,如果M.at<uchar>(i,j),則只能取到元素的第一個分量。

//用at的方式訪問矩陣元素
for(i=0; i< M.rows; i++)
    {
    for(j=0; j<M.cols; j++)
        {
        printf ("%d %d %d ", M.at<cv::Vec3b>(i,j)[0],M.at<cv::Vec3b>(i,j)[1], M.at<cv::Vec3b>(i,j)[2]);
        }
    printf("\n");
    }

}

2. 用c++迭代器的方式訪問。

cv::MatIterator_<cv::Vec3b> it, end;

for( it = M.begin<cv::Vec3b>(), end = M.end<cv::Vec3b>(); it != end; ++it)

{

    printf("%d %d %d\n",(*it)[0], (*it)[1], (*it)[2]);

}

程序源碼:工程FirstOpenCV2。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM