opencv之访问图像像素的 三种方法

来源:互联网 发布:娱乐圈小鲜肉知乎 编辑:程序博客网 时间:2024/05/17 22:01

opencv之访问图像像素

访问像素的三种方法

①指针访问:最快

②迭代器iterator:较慢,非常安全,指针访问可能出现越界问题

③动态地址计算:更慢,通过at()实现。适用于访问具体某个第i行,j列的像素,而不适用遍历像素

 

Mat在内存中存储形式

  灰度图的存储形式

    

 

  RGB的存储形式

  

一般情况下,Mat是连续存储的,按行连接。可以通过isContinuous()函数,判断矩阵是否连续存储,若连续返回true。

 

访问像素的三种方法

1.指针访问

void VisitImgByPointer(Mat &inputImg, Mat &dstImg){    dstImg = inputImg.clone();    int rows = dstImg.rows;    int cols = dstImg.cols * dstImg.channels();    for(int i = 0; i < rows; i++)    {        uchar* data = dstImg.ptr<uchar>(i);        for(int j = 0; j < cols; j++)        {            data[j] = 0;  //处理每一个像素            //add code        }    } }

当Mat按行连续存储时,可以用指针直接访问所有数据。

void VisitContinueImgByPointer(Mat &inputImg, Mat &dstImg){    dstImg = inputImg.clone();    int rows = dstImg.rows;    int cols = dstImg.cols;    int channels = dstImg.channels();    if(dstImg.isContinuous())    {        cols *= rows;        rows = 1;        //cout << "is continuous " << endl;    }    for(int i = 0; i < rows; i++)    {        uchar* data = dstImg.ptr<uchar>(i);        for(int j = 0; j < cols * channels; j++)        {            data[j] = 155;  //处理每一个像素            //add code        }    }     //若存储连续,等效于以下代码    //uchar* data = dstImg.data;    //for(int i = 0; i < cols * rows * channels; i++)    //    data[i] = 155;    //处理每一个像素}
2.迭代器访问

void VisitImgByIterator(Mat &inputImg, Mat &dstImg){    dstImg = inputImg.clone();    const int channels = dstImg.channels();      switch(channels)    {    case 1:        {            Mat_<uchar>::iterator it= dstImg.begin<uchar>();            Mat_<uchar>::iterator itend= dstImg.end<uchar>();            for ( ; it!= itend; it++) //处理每一个像素            {                *it = 150;            }            break;        }    case 3:        {            Mat_<Vec3b>::iterator it3= dstImg.begin<Vec3b>();            Mat_<Vec3b>::iterator itend3= dstImg.end<Vec3b>();            for ( ; it3!= itend3; it3++) //处理每一个像素            {                 (*it3)[0]= 255;                (*it3)[1]= 0;                (*it3)[2]= 0;            }            break;        }    }}

3.动态地址访问

void VisitImgByAt(Mat &inputImg, Mat &dstImg){    dstImg = inputImg.clone();    int rows = dstImg.rows;    int cols = dstImg.cols;    int channels = dstImg.channels();    switch(channels)    {    case 1:        {            for(int i = 0; i < rows; i++)                for(int j = 0; j < cols; j++)                    dstImg.at<uchar>(i,j) = 150;            break;        }    case 3:        {            for(int i = 0; i < rows; i++)                for(int j = 0; j < cols; j++)                {                    dstImg.at<Vec3b>(i,j)[0] =  0;                    dstImg.at<Vec3b>(i,j)[1] =  0;                    dstImg.at<Vec3b>(i,j)[2] = 255;                }            break;        }    }}

4. 测试代码

#include <iostream>#include <opencv2/opencv.hpp>  using namespace cv;using namespace std;void VisitImgByPointer(Mat &inputImg, Mat &dstImg);void VisitContinueImgByPointer(Mat &inputImg, Mat &dstImg);void VisitImgByIterator(Mat &inputImg, Mat &dstImg);void VisitImgByAt(Mat &inputImg, Mat &dstImg);int main(){    Mat srcImg = imread("pig.png"), dstImg;    Mat grayImg;    cvtColor(srcImg, grayImg, CV_BGR2GRAY);    //VisitImgByPointer(srcImg,dstImg);    //VisitContinueImgByPointer(grayImg,dstImg);        //VisitImgByIterator(srcImg,dstImg);    //VisitImgByIterator(grayImg,dstImg);        //VisitImgByAt(srcImg,dstImg);    VisitImgByAt(grayImg,dstImg);    //imshow("原始图", srcImg);    //imshow("灰度图", grayImg);    imshow("生成图", dstImg);    waitKey(0);    return 0;}void VisitImgByPointer(Mat &inputImg, Mat &dstImg){    dstImg = inputImg.clone();    int rows = dstImg.rows;    int cols = dstImg.cols * dstImg.channels();    for(int i = 0; i < rows; i++)    {        uchar* data = dstImg.ptr<uchar>(i);        for(int j = 0; j < cols; j++)        {            data[j] = 0;  //处理每一个像素            //add code        }    } }void VisitContinueImgByPointer(Mat &inputImg, Mat &dstImg){    dstImg = inputImg.clone();    int rows = dstImg.rows;    int cols = dstImg.cols;    int channels = dstImg.channels();    if(dstImg.isContinuous())    {        cols *= rows;        rows = 1;        //cout << "is continuous " << endl;    }    for(int i = 0; i < rows; i++)    {        uchar* data = dstImg.ptr<uchar>(i);        for(int j = 0; j < cols * channels; j++)        {            data[j] = 155;  //处理每一个像素            //add code        }    }     //若存储连续,等效于一下代码    //uchar* data = dstImg.data;    //for(int i = 0; i < cols * rows * channels; i++)    //    data[i] = 155;    //处理每一个像素}void VisitImgByIterator(Mat &inputImg, Mat &dstImg){    dstImg = inputImg.clone();    const int channels = dstImg.channels();      switch(channels)    {    case 1:        {            Mat_<uchar>::iterator it= dstImg.begin<uchar>();            Mat_<uchar>::iterator itend= dstImg.end<uchar>();            for ( ; it!= itend; it++) //处理每一个像素            {                *it = 150;            }            break;        }    case 3:        {            Mat_<Vec3b>::iterator it3= dstImg.begin<Vec3b>();            Mat_<Vec3b>::iterator itend3= dstImg.end<Vec3b>();            for ( ; it3!= itend3; it3++) //处理每一个像素            {                 (*it3)[0]= 255;                (*it3)[1]= 0;                (*it3)[2]= 0;            }            break;        }    }}void VisitImgByAt(Mat &inputImg, Mat &dstImg){    dstImg = inputImg.clone();    int rows = dstImg.rows;    int cols = dstImg.cols;    int channels = dstImg.channels();    switch(channels)    {    case 1:        {            for(int i = 0; i < rows; i++)                for(int j = 0; j < cols; j++)                    dstImg.at<uchar>(i,j) = 150;            break;        }    case 3:        {            for(int i = 0; i < rows; i++)                for(int j = 0; j < cols; j++)                {                    dstImg.at<Vec3b>(i,j)[0] =  0;                    dstImg.at<Vec3b>(i,j)[1] =  0;                    dstImg.at<Vec3b>(i,j)[2] = 255;                }            break;        }    }}

原文链接:http://www.cnblogs.com/kuotian/p/6389260.html?utm_source=itdadao&utm_medium=referral