OpenCV对图像遍历的高效方法

OpenCV对图像遍历的高效方法一、指针遍历首先介绍几个Mat类型的属性,rows是Mat类型的行数,cols是列数,channels()是通道数,那么对于图像的每一行,都有cols*channels()个像素点,所以我们可以对所有行进行遍历,然后对于特定一行,遍历所有像素点,代码如下:intnl=image.rows;//行数//每行的元素数量intnc=image.cols*i…

大家好,又见面了,我是你们的朋友全栈君。

一、指针遍历

        首先介绍几个Mat类型的属性,rows是Mat类型的行数,cols是列数,channels()是通道数,那么对于图像的每一行,都有cols*channels()个像素点,所以我们可以对所有行进行遍历,然后对于特定一行,遍历所有像素点,代码如下:

int nl= image.rows; // 行数
// 每行的元素数量
int nc= image.cols * image.channels();
for (int j=0; j<nl; j++) {
    // 取得行 j 的地址
    uchar* data= image.ptr<uchar>(j);
    for (int i=0; i<nc; i++) {
        // 处理每个像素 ---------------------
        data[i]= 0;
        // 像素处理结束 ----------------
    } // 一行结束
}

ptr也是一个模板属性,用来获取地址,而我们为什么要按行遍历而不直接从第一个元素位置直接遍历nl*nc个呢?

        这是因为在彩色图像中,图像数据缓冲区的前 3 字节表示左上角像素的三个通道的值,接下来的 3字节表示第 1 行的第 2 个像素,以此类推(注意 OpenCV 默认的通道次序为 BGR)。一个宽 W高 H 的图像所需的内存块大小为 W×H×3 uchars。不过出于性能上的考虑,我们会用几个额外的像素来填补行的长度。这是因为,如果行数是某个数字(例如 8)的整数倍,图像处理的性能可能会提高,因此最好根据内存配置情况将数据对齐。所以并不一定每行最后一个元素后边一定是下一行的第一个元素!

        但我们可以使用isContinuous()来检查是的有填充,如果没有填充,isContinuous()会返回true,所以我们可以采用下边方法遍历:

int nl= image.rows; // 行数
// 每行的元素总数
int nc= image.cols * image.channels();
if (image.isContinuous()) {
// 没有填充的像素
     nc= nc*nl;
     nl= 1; // 它现在成了一个一维数组
}

for (int j=0; j<nl; j++) {
    uchar* data= image.ptr<uchar>(j);
    for (int i=0; i<nc; i++) {
        *data++ = 0;
    } // 一行结束
}

 

二、迭代器遍历

        首先要介绍一下OpenCV的cv::Mat 实例的迭代器,首先要创建一个 cv::MatIterator_对象。跟 cv::Mat_类似,这个下划线表示它是一个模板子类。因为图像迭代器是用来访问图像元素的,所以必须在编译时就明确返回值的类型。可以这样定义彩色图像的迭代器:

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

        也可以使用在 Mat_模板类内部定义的 iterator 类型:

cv::Mat_<cv::Vec3b>::iterator it;

        然后就可以使用常规的迭代器方法 begin 和 end 对像素进行循环遍历了。不同之处在于它们仍然是模板方法。

 

        举个例子,对一张彩色图片进行遍历的代码为:

// 迭代器
cv::Mat_<cv::Vec3b>::iterator it= image.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::iterator itend= image.end<cv::Vec3b>();

// 扫描全部像素
for ( ; it!= itend; ++it) {
    //对像素点的处理
    (*it)[0] = 255;
    (*it)[1] = 255;
    (*it)[2] = 255;
}

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/138857.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 下载及安装Python详细步骤

    下载及安装Python详细步骤安装python分三个步骤:*下载python*安装python*检查是否安装成功1、下载Python(1)python下载地址https://www.python.org/download

    2022年7月3日
    22
  • c中getline的用法_enum用法

    c中getline的用法_enum用法getline()用法getline是C++标准库函数;它有两种形式,一种是头文件<istream>中输入流成员函数;一种在头文件<string>中普通函数;它遇到以下情况发生会导致生成的本字符串结束:(1)到文件结束,(2)遇到函数的定界符,(3)输入达到最大限度。输入流成员函数getline()函数语法结构:在<istream>中的g…

    2022年10月26日
    0
  • 黑盒测试的常见的测试用例设计方法有哪些[通俗易懂]

    黑盒测试的常见的测试用例设计方法有哪些[通俗易懂]测试用例怎么设计?一般根据业务知识掌握,之前已有的回归测试用例,测试知识库,测试需求开始设计。黑盒测试的常见的测试用例设计方法有哪些?1)等价类划分:等价类是指某个输入域的子集合.在该子集合中,各个输入数据对于揭露程序中的错误都是等效的.并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试.因此,可以把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件,就可以用少量代表性的测试数据.取得较好的测试结果.等价类划分可有两种不同的情况:有效等价类和无效等价类.

    2022年6月29日
    21
  • 创业型互联网公司应该选择PHP, JavaEE还是.NET技术路线?

    通常JavaEE和.NET被定义为构建大型在线系统,因为其支持面向对象设计,异步通讯,MVC等都相对比较完善,而PHP通常用于构建比较轻量的业务,例如SNS服务。因为实施速度快,工程师社区规模大,开源

    2021年12月20日
    41
  • Linux 学习之 MQTT 服务器搭建「建议收藏」

    Linux 学习之 MQTT 服务器搭建「建议收藏」摘要:前言博主之前写了一篇《在Windows下搭建MQTT服务器》,这次要尝试在Ubuntu下搭建MQTT服务器。实际上,下载好源码包后,后面的都和那篇文章差不多了。开发环境虚拟机Ubuntu14.04.5LTSApache-Apollo-1.7.1准备工作由于搭建Apollo环境变量需要有JAVA_HOME,这个时候需要安装JDK,可以参考这篇文章:《Ubuntu安装JDK1.8.0并配置环境变…

    2022年5月10日
    33
  • spring任务调度scheduled_golang 任务调度

    spring任务调度scheduled_golang 任务调度1、任务调度接口TaskScheduler提供了多种方法来调度将来某个时间点要运行的任务。2、触发器Trigger实现PeriodicTrigger和CronTrigger。3、@Scheduled注解创建定时任务4、@Async注解异步方法执行,value属性指定任务执行器。5、task:scheduler、task:executor创建调度器和执行器…

    2022年10月11日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号