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++;  
    }  
} 

 

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