C++版Opencv3.0 遍历访问像素的方法以及ptr与at的详细区别

前言

1.1 Mat类简介及如何创造一个Mat对象

在学习opencv进行图像处理的时候,遇到的第一个类就是Mat对象。关于Mat类的介绍以及用法还有如何创建一个Mat对象如这篇博文所示:

https://blog.csdn.net/CV_Jason/article/details/54928920

为了进一步形象的理解Mat对象的数据存储方式,参考以下内容

图像容器Mat
还是先看Mat的存储形式。Mat和Matlab里的数组格式有点像,但一般是二维向量,如果是灰度图,一般存放<uchar>类型;如果是RGB彩色图,存放<Vec3b>类型。
单通道灰度图数据存放格式:

多通道的图像中,每列并列存放通道数量的子列,如RGB三通道彩色图:

注意通道的顺序反转了:BGR。通常情况内存足够大的话图像的每一行是连续存放的,也就是在内存上图像的所有数据存放成一行,这中情况在访问时可以提供很大方便。可以用 isContinuous()函数来判断图像数组是否为连续的。
原文链接:https://blog.csdn.net/xiaowei_cqu/article/details/7771760

1.2 访问像素的方法总结

主要参考以下博文:

https://blog.csdn.net/xiaowei_cqu/article/details/19839019

1.3 实例

#include<iostream>
#include<opencv2/opencv.hpp>
#include<math.h>

using namespace cv;
using namespace std;


int main(int argc,char*argv[]){
    Mat src;
    src = imread("F:\\opencv练习\\C++Test\\1-data image process\\2-图像卷积\\test.jpg");
    if (!src.data)
    {
        cout << "It could not load image..." << endl;
        return -1;
    }
    namedWindow("original image",WINDOW_AUTOSIZE);
    imshow("original image", src);
    //像素访问方法Mat类存储灰度图像时用<uchar>类型,存储rgb图像时用<Vec3b>类型
    //第一种:使用.ptr<>()和[]
    Mat gray_src;
    cvtColor(src, gray_src, COLOR_BGR2GRAY);
    namedWindow("gray image", WINDOW_AUTOSIZE);
    imshow("gray image",gray_src);
    cout << gray_src.size() << endl;
    int col = gray_src.cols;//表示列
    int row = gray_src.rows;//表示行
    
    /*for (int i = 0; i < row;i++)
    {
        const uchar*data = gray_src.ptr<uchar>(i);
        for (int j = 0; j < 5;j++)
        {
             out_put = data[j];
            cout << out_put << endl;
            //int gray = gray_src.at<uchar>(i, j);
               // gray_src.at<uchar>(i, j) = 255 - gray;
        }
    }    */
    //第二种方法:使用.ptr<>()和位移指针*++的组合方法访问某一行中所有像素的值
    /*for (int i = 0; i < 1;i++)
    {
        const uchar*data = gray_src.ptr<uchar>(i);
        for (int j = 0; j < col;j++)
        {
            
            int  out_put= *data++;
            
             cout << out_put << endl;
             
        }
    }*/
    

    //第三种方法:用Mat提供的迭代器Mat _iterator
    cv::Mat_<cv::Vec3b>::iterator it = src.begin<cv::Vec3b>();
    cv::Mat_<cv::Vec3b>::iterator itend = src.end<cv::Vec3b>();
    for (; it != itend; ++it)
    {
        int a= (*it)[0];
        int b = (*it)[1];
        int c = (*it)[2]; 
        //cout << a << b << c << endl;
        cout << *it << endl;
    }waitKey(0);
    
    return 0;
}

1.3  Mat像素访问指针ptr<>与at<>的用法区别

具体的区别和用法参见下面的博客

https://blog.csdn.net/u011574296/article/details/70139563

最快区别为

使用ptr指针访问像素时访问任意一行像素的首地址,特别方便图像的一行一行的横向访问,如果需要一列一列的纵向访问图像,就稍微麻烦一点,<>中一般是uchar。

使用at访问像素时,使用调用方法image.at<cv::Vec3b>(j,i),at方法方便,直接给i,j赋值就可以随意访问图像中任何一个像素,其中j表示第j行,i表示该行第i个像素。<>中一般是Vec3b

 


            
    
    

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值