opencv 遍歷mat的三種方法

灰度圖在內存中的存儲形式

3通道圖在內存中的存儲形式

1. 通過 .at<typename>(i,j) 遍歷

void colorReduce(Mat& image,int div)  
{  
    for(int i=0;i<image.rows;i++)  
    {  
        for(int j=0;j<image.cols;j++)  
        {  
            image.at<Vec3b>(i,j)[0]=image.at<Vec3b>(i,j)[0]/div*div+div/2;  
            image.at<Vec3b>(i,j)[1]=image.at<Vec3b>(i,j)[1]/div*div+div/2;  
            image.at<Vec3b>(i,j)[2]=image.at<Vec3b>(i,j)[2]/div*div+div/2;  
        }  
    }  
}  

image.at<uchar>(i,j):取出灰度圖像中i行j列的點。

image.at<Vec3b>(i,j)[k]:取出彩色圖像中i行j列第k通道的顏色點,k=[0,1,2],分別代表B,G,R。

uchar,Vec3b都是圖像像素值的類型,在core裏它是通過typedef Vec<T,N>來定義的,N代表元素的個數,T代表類型。

OpenCV定義了一個Mat的模板子類爲Mat_,它重載了operator()讓我們可以更方便的取圖像上的點。

Mat m2(300, 500, CV_8UC3, Scalar(0, 0, 0));
Mat_<Vec3b> im = m2;
for (int i = 0; i < im.rows; i++) {
    for (int j = 0; j < im.cols; j++) {
        im(i, j)[0] = im(i, j)[0] + (uchar) (255 / 2);
        im(i, j)[1] = im(i, j)[1] + (uchar) 0;
        im(i, j)[2] = im(i, j)[2] + (uchar) (111 / 2);
    }
}

2. 通過行指針 .ptr<uchar>(k)來遍歷

void colorReduce(const Mat& image,Mat& outImage,int div)  
{  
    // 創建與原圖像等尺寸的圖像  
    outImage.create(image.size(),image.type());  
    int nr=image.rows;  
    // 將3通道轉換爲1通道  
    int nl=image.cols*image.channels();  
    for(int k=0;k<nr;k++)  
    {  
        // 每一行圖像的指針  
        const uchar* inData=image.ptr<uchar>(k);  
        uchar* outData=outImage.ptr<uchar>(k);  
        for(int i=0;i<nl;i++)  
        {  
            outData[i]=inData[i]/div*div+div/2;  
        }  
    }  
} 

3. 通過迭代器Mat_iterator來遍歷

void colorReduce(const Mat& image,Mat& outImage,int div)  
{  
    outImage.create(image.size(),image.type());
    // 獲得迭代器  
    MatConstIterator_<Vec3b> it_in=image.begin<Vec3b>();  
    MatConstIterator_<Vec3b> itend_in=image.end<Vec3b>();  
    MatIterator_<Vec3b> it_out=outImage.begin<Vec3b>();  
    MatIterator_<Vec3b> itend_out=outImage.end<Vec3b>();  
    while(it_in!=itend_in)  
    {  
        (*it_out)[0]=(*it_in)[0]/div*div+div/2;  
        (*it_out)[1]=(*it_in)[1]/div*div+div/2;  
        (*it_out)[2]=(*it_in)[2]/div*div+div/2;  
        it_in++;  
        it_out++;  
    }  
} 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章