图像容器Mat

Mat和Matlab里的数组格式有点像,但一般是二维向量,如果是灰度图,一般存放<uchar>类型;如果是RGB彩色图,存放<Vec3b>类型。
单通道灰度图数据存放格式:
多通道的图像中,每列并列存放通道数量的子列,如RGB三通道彩色图:
有一点需要注意:图像的通道顺序是:BGR。通常情况内存足够大的话图像的每一行是连续存放的,也就是在内存上图像的所有数据存放成一行,这中情况在访问时可以提供很大方便。

好了,下面总结一下常见的访问图像像素的三种方法:使用at动态地址计算方式,使用iterator迭代器方式,使用ptr指针。先附代码:

#include <iostream>
#include<core/core.hpp>
#include<highgui/highgui.hpp>
using namespace cv;
using namespace std;
void colorReduceAt(Mat& srcImage, Mat& dstImageAt, int div);
void colorReduceIterator(Mat& srcImage, Mat& dstImageIterator, int div);
void colorReducePtr(Mat& srcImage, Mat& dstImagePtr, int div);
int main()
{    Mat image=imread("e:\\kobe.jpg"); Mat mv[3];split(image,mv); if(!image.data)  {  cout<<"you idiot!where did you hide kobe!"<<endl;     system("pause");  return -1;  }    //声明处理后图像变量Mat dstImageAt, dstImageIterator, dstImagePtr;dstImageAt = image.clone();dstImageIterator = image.clone();dstImagePtr = image.clone();int div = 4;
//声明时间变量double timeAt, timeIterator, timePtr;timeAt = static_cast<double>(getTickCount());colorReduceAt(image, dstImageAt, div);timeAt = ((double)getTickCount() - timeAt) / getTickFrequency();namedWindow("dstImageAt",CV_WINDOW_NORMAL);imshow("dstImageAt",dstImageAt);cout << "使用at()动态地址计算耗时:" << timeAt << endl << endl;timeIterator = static_cast<double>(getTickCount());colorReduceIterator(image, dstImageIterator, div);timeIterator = ((double)getTickCount() - timeIterator) / getTickFrequency();namedWindow("dstImageIterator",CV_WINDOW_NORMAL);imshow("dstImageIterator",dstImageIterator);cout << "使用iterator迭代器耗时:" << timeIterator << endl << endl;timePtr = static_cast<double>(getTickCount());colorReducePtr(image, dstImagePtr, div);timePtr = ((double)getTickCount() - timePtr) / getTickFrequency();namedWindow("dstImagePtr",CV_WINDOW_NORMAL);imshow("dstImagePtr",dstImagePtr);cout << "使用ptr指针耗时:" << timePtr << endl;
//等待按键waitKey();  return 0;
}  //使用at动态地址计算方式
void colorReduceAt(Mat& srcImage, Mat& dstImageAt, int div)
{int rowNumber = dstImageAt.rows;      //获取图像行数int colNumber = dstImageAt.cols;      //获取图像列数//对每个像素进行处理for(int i = 0; i < rowNumber; i++){for(int j = 0; j < colNumber; j++){dstImageAt.at<Vec3b>(i,j)[0] = dstImageAt.at<Vec3b>(i,j)[0]/div*div;    //B通道dstImageAt.at<Vec3b>(i,j)[1] = dstImageAt.at<Vec3b>(i,j)[1]/div*div;    //G通道dstImageAt.at<Vec3b>(i,j)[2] = dstImageAt.at<Vec3b>(i,j)[2]/div*div;    //R通道}}}//使用iterator迭代器方式
void colorReduceIterator(Mat& srcImage, Mat& dstImageIterator, int div)
{MatIterator_<Vec3b> imageIt = dstImageIterator.begin<Vec3b>();      //获取迭代器初始位置MatIterator_<Vec3b> imageEnd = dstImageIterator.end<Vec3b>();       //获取迭代器结束位置//对每个像素进行处理for(;imageIt != imageEnd; imageIt++){(*imageIt)[0] = (*imageIt)[0]/div*div;      //B通道(*imageIt)[1] = (*imageIt)[1]/div*div;      //G通道(*imageIt)[2] = (*imageIt)[2]/div*div;      //R通道}
}//使用ptr指针
void colorReducePtr(Mat& srcImage, Mat& dstImagePtr, int div)
{int rowNumber = dstImagePtr.rows;                           //获取图像矩阵行数int colNumber = dstImagePtr.cols*dstImagePtr.channels();    //三通道图像矩阵列树=图像列数x通道数for(int i = 0; i < rowNumber; i++){uchar* pixelPtr = dstImagePtr.ptr<uchar>(i);            //获取矩阵每行首地址指针for(int j = 0; j < colNumber; j++)pixelPtr[j] = pixelPtr[j] / div * div;}
}

运行结果如下:

并且发现,使用ptr方式访问像素用时最少。

参考:

https://yq.aliyun.com/articles/9300

http://www.cnblogs.com/zjgtan/archive/2013/04/06/3002962.html

http://blog.csdn.net/keith_bb/article/details/53071133

后来新发现一篇比较全的博文介绍:http://blog.csdn.net/xiaowei_cqu/article/details/19839019

opencv图像像素操作方法相关推荐

  1. 第三章 Opencv图像像素操作

    目录 1.像素 1-1.确定像素位置 1-2.获取指定像素的像素值 1-3.修改像素的BGR值 2.用numpy模块操作像素 2-1.创建图像 1.创建黑白图像 2.创建彩色图像 3.创建随机图像 2 ...

  2. C++Opencv图像像素操作

    Mat对象与数学中的矩阵相似,也可以实现加减乘除. //像素值加法 Mat operator_demo1(Mat& image) {Mat dst;dst = image + Scalar(5 ...

  3. OpenCV图像像素遍历与访问

    遍历方式有很多种,下面给出两种方式: 基于数组遍历 基于指针遍历 1.基于数组遍历 Mat类中的cols.rows为图像的宽.高.成员函数at(row,col)可以存取图像元素.对于包含彩色图像的Ma ...

  4. opencv 图像像素比较

    小白学视觉,笔记 1 两图像比较,取大,取小 2 最大值.最小值 1 两图像比较,取大,取小 lena图像white.black图像比较,取大,取小. 比较之前图像大小已调整一致. #include ...

  5. Python+OpenCV 图像处理系列(4)—— 图像像素的读写、算术运算、逻辑运算及像素的统计

    1. 像素的读写 可以根据像素的行和列的坐标获取它的像素值.对 BGR 图像而言,返回值为 B,G,R 的值. img.shape 可以获取图像的形状.它的返回值是一个包含行数 h,列数 w,通道数 ...

  6. OpenCV(一)图像读取与新建、图像显示、操作图像像素(2种涂色并比较算法优劣、输出RGB)

    目录 一.读取图像与新建图像 1.读取图像 2.新建图像 二.显示图像 1.过程 2.代码 3.运行效果 三.操作图像像素 1.逐RGB涂色(单循环)(快) 1-1.过程 2-2.代码 2-3.运行结 ...

  7. 【OpenCV 4开发详解】图像像素统计

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  8. dataset中获取图像的名字_GDAL与OpenCV的图像像素读取格式互相转换

    前言 任务原因,遇到了一个需要GDAL图像像素格式与OpenCV相互转换的问题,解决之后顺便记录一下. 正文 OpenCV(Open Source Computer Vision Library)是一 ...

  9. OpenCV计算机视觉编程之三种图像像素的遍历方法

    为了构建计算机视觉应用程序,需要学会访问图像内容,有时也要修改或创建图像,如何操作图像的像素,就需要遍历一幅图像并处理每一个像素.现在我们就来介绍OpenCV三种图像像素的遍历方法: 一. 用cv:: ...

  10. opencv C++ 三重for循环遍历RGB图像像素(逐像素操作、操作像素值、遍历像素遍历)at<typename>(i,j)、灰度图at<uchar>、at<Vec3b>、at<Vec3F>

    示例:数组遍历法at<typename>(i,j) -- 其中一种方法(速度可能并不是很快),如果对速度有要求可查看参考文章2里的其他方法 #include <opencv2/ope ...

最新文章

  1. 他24岁,4篇Nature在手,也会关心学不懂C语言怎么办
  2. C++ 获得指定路径文件的“修改日期”
  3. python在哪里写程序和运行-如何编写和运行Python程序
  4. vue和layui哪个更好用_幕布和Mind+思维导图哪个更好用?
  5. 手撕 CNN 经典网络之 AlexNet(理论篇)
  6. c语言编写电子秒表程序,电子秒表C程序.doc
  7. Java StreamTokenizer nextToken()方法与示例
  8. linux网络编程之socket:使用fork并发处理多个client的请求
  9. 剑指offer——3.实现数组中重复数字查找
  10. php四种基础算法:冒泡,选择,插入和快速排序法PHP基础教程
  11. 计算机英语听力速记...,2019计算机考研英语听力速记技巧才是王道
  12. echarts饼图选中一块_echarts圆饼图设置默认选中项并在中间显示文字
  13. 星星之火-34:傅里叶分析的9大步骤
  14. Springboot实现阿里云通信短信服务有关短信验证码的发送
  15. 提取Wallpaper engineer里面scene.pkg文件的内容
  16. 黑盒测试用例编写八大方法
  17. 在win10系统中应用iverilog(Icarus verilog)学习笔记
  18. 天猫双十一红包口令玩法
  19. java计算机毕业设计Internet快递柜管理系统(附源码、数据库)
  20. postgresql分割字符串_PostgreSQL 字符串拆分与合并案例

热门文章

  1. Go中函数作为值、类型传递。
  2. atom无法安装插件的解决方法之一
  3. jquery 几个实用的小方法
  4. Android客户端和服务器端数据交互的第三种方法
  5. 10 分钟实现 Spring Boot 发送邮件功能
  6. CentOS7安装dnf
  7. .Net读取Excel的数据类型不统一获取空值问题
  8. ssh-key生成密钥及SSH无密码登录的配置(转载)
  9. 44. Factor parameter-independent code out of templates.
  10. php 简繁体字同时显示_(C++/php/Swift/Go/Ruby 篇)2020 年最火编程语言出炉!关键特性、普及程度、薪资全方位解读...