根据OpenCV中Mat类型的结构和内存中存储方式,此处给出三种对图像进行遍历的方法。首先给出基础的读取图片代码,在中间替换三种遍历方法即可,本文中,程序将遍历图像并将所有像素点置为255,所有运行结果中命令行里的数字为程序执行时间

#include "stdafx.h"
#include <opencv2/core/core.hpp>
#include "highgui.h"
#include <iostream>
using namespace cv;
using namespace std;
int main() {
Mat image = imread("D:\\Users\\Documents\\WinForm\\cpp_learn\\teach1\\Debug\\img.jpg",CV_LOAD_IMAGE_COLOR);//读取img.jpg到image中,此处可以写相对路径也可以写绝对路径
namedWindow("图片1");//定义一个名为“图片1”的窗口
imshow("图片1", image);//在窗口“图片1”中显示image double time = static_cast<double>(cv::getTickCount()); //遍历元素 time = static_cast<double>(cv::getTickCount()) - time;
time /= cv::getTickFrequency();
cout<<time<<endl; namedWindow("图片2");//定义一个名为“图片1”的窗口
imshow("图片2", image);//在窗口“图片1”中显示image
waitKey();
return ;
}

一、一个一个点的读取

  作为最低效率的一种方法,本法的思想就是从第一行第一列开始依次读第一行第二列、第三列,然后是第二行、第三行。其核心代码就是

image.at<uchar>(i,j)//读取灰度图像的点
image.at<cv::Vec3b>(i,j)[]//读取彩色图像点的0通道

该方法可以读取图像中i行j列的点,代码如下:

    for (int i = ; i < image.rows; i++)
{
for (int j = ; j < image.cols; j++)
{
//Do anything you want
if(image.channels() == )
{
image.at<uchar>(i,j) = ;
}
else if(image.channels() == )
{
image.at<cv::Vec3b>(i,j)[] = ;
image.at<cv::Vec3b>(i,j)[] = ;
image.at<cv::Vec3b>(i,j)[] = ;
}
}
}

二、 通过指针遍历图像

  由于Mat图像在内存中是连续排布的,因此定义指针指向行首地址后,指针每+1就会移到下一个元素上,此时直接操作指针所指内容就可以实现图像的操作。

    int image_rows = image.rows;//行数
int elementCount = image.cols*image.channels();//每行元素数
if (image.isContinuous())//如果图像没有经过填补 内存是连续排序
{
//则把图像看成行数X每行元素数个元素的一行,只进行一次循环
elementCount = elementCount*image_rows;
image_rows = ;
}
for (int i = ; i < image_rows; i++)
{
uchar* linehead = image.ptr<uchar>(i);//每行的起始地址
for (int j = ; j < elementCount; j++)
{
//遍历元素 Do anything you want
linehead[j] = ;
}
}

  值得注意的是,在内存上行与行之间的元素可能不是连续的(有时为提高效率,会将行元素填补为4的倍数),因此如果要连续用指针遍历图像,首先应判断图像是否有填补。

三、迭代器遍历

  这个和指针比较像,不细说了,上代码。

    Mat_<Vec3b>::iterator it = image.begin<Vec3b>();
Mat_<Vec3b>::iterator itend = image.end<Vec3b>();
for (; it!= itend; it++)
{
(*it)[] = ;
(*it)[] = ;
(*it)[] = ;
}

OpenCV2+入门系列(三):遍历图像的几种方法的更多相关文章

  1. mybatis入门系列三之类型转换器

    mybatis入门系列三之类型转换器 类型转换器介绍 mybatis作为一个ORM框架,要求java中的对象与数据库中的表记录应该对应 因此java类名-数据库表名,java类属性名-数据库表字段名, ...

  2. C# 互操作性入门系列(三):平台调用中的数据封送处理

    好文章搬用工模式启动ing ..... { 文章中已经包含了原文链接 就不再次粘贴了 言明 改文章是一个系列,但只收录了2篇,原因是 够用了 } --------------------------- ...

  3. [转]C# 互操作性入门系列(三):平台调用中的数据封送处理

    参考网址:https://www.cnblogs.com/FongLuo/p/4512738.html C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列( ...

  4. c#图像处理入门(-bitmap类和图像像素值获取方法)

    c#图像处理入门 -bitmap类和图像像素值获取方法 一.Bitmap类 Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义 ...

  5. 转载:遍历Map的四种方法

    http://www.cnblogs.com/kristain/articles/2033566.html 遍历Map的四种方法 public static void main(String[] ar ...

  6. java 遍历map的四种方法

    16:21:42 Map.entrySet() 这个方法返回的是一个Set<Map.Entry<K,V>>,Map.Entry 是Map中的一个接口,他的用途是表示一个映射项( ...

  7. WPF编程,将控件所呈现的内容保存成图像的一种方法。

    原文:WPF编程,将控件所呈现的内容保存成图像的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/detai ...

  8. 遍历python字典几种方法

    遍历python字典几种方法 from: http://ghostfromheaven.iteye.com/blog/1549441 aDict = {'key1':'value1', 'key2': ...

  9. CSS三栏布局的四种方法

    总括: 不管是三栏布局还是两栏布局都是我们在平时项目里经常使用的,也许你不知道什么事三栏布局什么是两栏布局但实际已经在用,或许你知道三栏布局的一种或两种方法,但实际操作中也只会依赖那某一种方法,本文具 ...

随机推荐

  1. Android四大核心组件之Service

    实验内容 启动Service 绑定Service 与Service进行通信 实验要求 启动Service 绑定Service 与Service进行通信 实验步骤 Service概述 Service通常 ...

  2. DNS CNAME的一些细节

    1, 概述 DNS中的CNAME可以减轻运维压力,使得已有的DNS配置具有一定的灵活性和可扩展性.本文对CNAME中的一些细节做阐述, 使DNS服务器的运维人员和开发人员能合理地使用CNAME. 2, ...

  3. python入门到精通[二]:基础学习(1)

    摘要:Python基础学习: 注释.字符串操作.用户交互.流程控制.导入模块.文件操作.目录操作. 上一节讲了分别在windows下和linux下的环境配置,这节以linux为例学习基本语法.代码部分 ...

  4. 在html中引用分享的链接

    怎么说呢,其实我自己本身也不是很懂,这些到网上一搜也是有很多详解的,我就是水水的来~~ 附带:smarty 的 tpl 里面 要直接写 javascript 或 style 要用 literal 标签 ...

  5. ZooKeeper的Znode剖析

    在ZooKeeper中,节点也称为znode.由于对于程序员来说,对zk的操作主要是对znode的操作,因此,有必要对znode进行深入的了解. ZooKeeper采用了类似文件系统的的数据模型,其节 ...

  6. paper 115:常见的概率分布(matlab作图)

    一.常见的概率分布 表1.1 概率分布分类表 连续随机变量分布 连续统计量分布 离散随机变量分布 分布 分布 二项分布 连续均匀分布 非中心 分布 离散均匀分布 (Gamma)分布 分布 几何分布 指 ...

  7. net core 控制台中文乱码的解决方案

    net core 对控制台中文的支持需要加入下面的语句 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

  8. 补全Gemfile缺少到javascript gem

    如果缺少某个gem,查看并修改Gemfile文件 第一步要先修改源 source 'https://ruby.taobao.org' 下面补全这两个gem gem 'execjs' gem 'ther ...

  9. Http状态码(转)

    什么是Http状态码?(转自http://bbs.tui18.com/thread-11597640-1-1.html) 百度百科上解释为:HTTP状态码(HTTP Status Code)是用以表示 ...

  10. JDK的安装与Java环境变量的配置详解

    JDK作为JAVA开发的环境,必须在电脑上安装JDK. 1.下载jdk http://rj.baidu.com/soft/detail/14459.html?ald下载jdk最新版jdk-8u11-w ...