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

 

 

 

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 微服务架构(java环境&tomcat)

    微服务架构(java环境&tomcat)

  • yum 命令讲解「建议收藏」

    yum 命令讲解「建议收藏」(一)yum介绍Yum(全称为YellowdogUpdater,Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装。yum提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁而又好记。 …

  • 大学最应该学习的 5 门课, 毕业后大厂 Offer 直接拿到手软!「建议收藏」

    大学最应该学习的 5 门课, 毕业后大厂 Offer 直接拿到手软!「建议收藏」时间如白驹过隙,我竟然已经是一名拥有13年编程经验的老油条了!有些自豪,因为自己从大一就开始学习的Java语言依然坚挺,几乎是编程语言中的霸主了;但也有些遗憾,大学的时候没有把这些计算机基础课程学好,有些甚至没有学,导致工作后有很长一段时间蛮吃力的,全靠近些年“废寝忘食”的补课,才有所好转。希望学弟学妹们,能从我这些经验中获得一些启发,少走一些弯路。1)计算机编程的基石——数据结构与算法2)计算机编程语言的母胎——C语言3)计算机组成原理4)计算机操作系统5)计算机网络一、数据结构

  • jquery

    jquery

  • creating server tcp listening socket 127.0.0.1:6379: bind No error

    creating server tcp listening socket 127.0.0.1:6379: bind No errorwindow下启动redis服务报错:creatingservertcplisteningsocket127.0.0.1:6379:bindNoerror的解决方案如下按顺序输入如下命令就可以连接成功redis-cli.exeshutdownexitredis-server.exeredis.windows.conf参考连接:https://blog.csdn….

  • mysql长轮询_ajax的轮询和长轮询

    mysql长轮询_ajax的轮询和长轮询概念:轮询(polling):客户端按规定时间定时像服务端发送ajax请求,服务器接到请求后马上返回响应信息并关闭连接。概念总是枯燥的,只有代码方能解心头之快前段代码:index.html:vargetting={url:’server.php’,dataType:’json’,success:function(res){console.log(res);}};//关键在这里,Ajax定时…

发表回复

您的电子邮箱地址不会被公开。

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