Mat中两种像素遍历方法比较
小白,入门中,不足其指正。刚刚接触opencv,从一个Matlab风格的编程环境突然跳转到C++,实在有些不适。单就pixels scanning花了好长时间研究。opencv-tutorials给出了四种方法。这里将比较其中最高效的方法与Mat类里定义的at()的效率。
本文以opencv-tutorials中给出的color reduction 为例进行比较。
- 图像的读取
为了简化问题,直接对灰度图进行操作,灰度图的获取可以用Mat类里的imread函数(每每看到这个函数都很激动,又有了Matlab的感觉)。
//read the image data
Mat GrayImage;
GrayImage = imread("test.jpg",);
//show the image that read
namedWindow("OriginalGrayImage");
imshow("OriginalGrayImage",GrayImage);
其中imread的参数0表示的就是读取灰度图。相比于Matlab里面还要用rgb22gray转化,这里就方便一点了哈!
原图:

灰度读取效果:

- lookup table的产生
我们的目的是把读取的图像像素值进行量化,如果将0~255的像素量化成4级,就需将0~63的像素计算成0,64~127的像素计算成为64……
因为在C++编译过程中,uchar/int的结果还是uchar,所以直接利用下面公式就可以得到

注意的是这里我用的是opencv.org上盗的图,图中的10可以用dividewidth替换,dividewidth的值需要根据量化的结果来确定,比如如果dividewidth=64;那么0~63的像素都会计算成0,64~127的像素都会计算成为64……以此类推,这样就会被量化成4级。
但是值得注意的是,对于一张100*100的灰度图就需要计算10000次,所以lookup table产生了。lookup table的思路是产生一个0~255的向量,没个存放用上述公式计算的结果,然后遍历的时候只需要查表就可以了,这样对于一个100*100的灰度图,本来需要计算10000次的,现在只需要计算256次。
产生lookup table的代码段
uchar table[];
int div = ;
for(int i=;i<;i++)
table[i] = (uchar)(div*(i/div));
- 灰度量化-classic C style operator[]
Mat.ptr<type>(i)可以获得第i行的指针,其中type表示的是Mat中存放的数据类型,一般的灰度图为uchar,rgb图则是Vec3b。Mat.rows和Mat.cols中分别存放的是图像的行数和列数。
具体代码段如下
//get some informations from GrayImage
int nr = GrayImage.rows;
int nc = GrayImage.cols;
uchar* p;
for(int i=0;i<nr;i++)
{
p = GrayImage.ptr<uchar>(i);
for(int j=0;j<nc;j++)
{
p[j] = table[p[j]];
}
}
运行结果:

灰度量化-Mat.at<type>(i,j)
for(int i=;i<nr;i++)
for(int j=;j<nc;j++)
GrayImage.at<uchar>(i,j) = table[GrayImage.at<uchar>(i,j)];
运行结果:

如何获得运行时间
opencv中提供了两个函数,getTickCount()和getTickFrequency();
Well OpenCV offers two simple functions to achieve this getTickCount() and getTickFrequency().
opencv.org盗来的代码段:
double t = (double)getTickCount();
// do something ...
t = ((double)getTickCount() - t)/getTickFrequency();
cout << "Times passed in seconds: " << t << endl;
- 结果比较
|
classic C style operator[] |
0.00136458 |
| Mat.at<type>(i,j) | 0.00498963 |
从结果可以看出,指针操作明显更高效,这也就是为什么opencv-tutorials中把它称为the effective way的原因。但是,指针操作有危险性,所以很多人还是原因用Mat.at的方法。
Mat中两种像素遍历方法比较的更多相关文章
- Python中两种处理错误方法的比较
我所说的处理错误的方法,其实是try:,except和raise这两种. 首先抛出一个实例, dictt={'a':1,'b':2,'c':3} try: if dictt['d']>1: #字 ...
- UWP开发中两种网络图片缓存方法
通常情况下,我们的程序需要从服务器读取图片,但如果需要不止一次读取某一张图片的话,就需要做本地缓存了,这样既为用户省一点流量,又能显得你的APP很快. 假如你已经知道了某一张图片的地址,那么第一件事就 ...
- Cesium 中两种添加 model 方法的区别
概述 Cesium 中包含两种添加 model 的方法,分别为: 通过 viewer.entities.add() 函数添加 通过 viewer.scene.primitives.add() 函数添加 ...
- python中两种拷贝目录方法的比较
首先是用python自己的api: shutil.copytree('./build/tested/doc', './build/tested/build/doc') 优点是改变平台时不需要修改代码, ...
- JAVA 中两种判断输入的是否是数字的方法__正则化_
JAVA 中两种判断输入的是否是数字的方法 package t0806; import java.io.*; import java.util.regex.*; public class zhengz ...
- JavaScript 中的12种循环遍历方法
原文:JavaScript 中的12种循环遍历方法 题目:请介绍 JavaScript 中有哪些循环和遍历的方法,说说它们的应用场景和优缺点? 1.for 循环 let arr = [1,2,3];f ...
- jsp中两种include的区别【转】
引用文章:http://www.ibm.com/developerworks/cn/java/j-jsp04293/ http://www.cnblogs.com/lazycoding/archive ...
- OC中两种单例实现方式
OC中两种单例实现方式 写在前面 前两天探索了一下C++ 的单例,领悟深刻了许多.今天来看看OC中的单例又是怎么回事.查看相关资料,发现在OC中一般有两种实现单例的方式,一种方式是跟C++ 中类似的常 ...
- 关于js中两种定时器的设置及清除(转载)
1.JS中的定时器有两种: window.setTimeout([function],[interval]) 设置一个定时器,并且设定了一个等待的时间[interval],当到达时间后,执行对应的方法 ...
随机推荐
- 如何将office卸载干净
我试了控制面板卸载office软件等方法,发现一直卸载不干净. 后发现这个office的官方链接,根据这个链接的步骤就很轻松的卸载好了. https://support.office.com/zh-c ...
- No.1011_第八次团队会议
罗老师和Bigman助教: 一直以来没看博客页面,我们的博客负责人不是没写博客,而是不小心把博客发到草稿上了.. 请您再次看一下我们的博客,并批评指正! 今天大家的情绪依旧很低落,离第一轮迭代完成距离 ...
- Linux 下Web环境搭建————redis
1.安装编译工具(yum -y install make gcc gcc-c++ ncurses-devel)2 2.安装tcl依赖 yum -y install tcl 3.上传redis安装包并解 ...
- 手机访问本地php项目遇到的问题及解决
做html5的本地应用要调试后台,学了下php 按照和连j2ee的时候一样,电脑发射wifi,ipconfig..等等 发现tomcat的可以访问,apache的不能访问,搜索好久,没找到解答, j ...
- Java第二天——标识符命名规则、Java的知识、快捷键的使用、Scanner获取值的常用方法
1.标识符命名规则 字母.下划线.数字.美元符号($)由这四个部分组成. 标识符=首字母+其他 首字母:字母.下划线.美元符号($) 其他:字母.下划线.数字.美元符号($) 注意: 1.首字母不能为 ...
- windows下的C++ socket服务器(4)
void handleAccept(int socket_fd) { ] = { '\0' }; string cmd; string filename; recv(socket_fd, buf, ) ...
- 关于mybatis的思考(2)——mybatis映射文件的深入理解
1.配置文件 mybatis进行持久化操作是以SqlSessionFactory对象为基础的,这个对象是整个数据库映射关系经过编译后的内存镜像. InputStream inputStream = R ...
- Ubuntu恢复被误删的文件
主要内容转载自博客:https://blog.csdn.net/YLD10/article/details/80241160 写在前面,该方法只能用于误删的文件,若文件被覆盖,则无法恢复. 1.下载工 ...
- 【大数据应用技术】作业八|爬虫综合大作业Molly134
本次作业的要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3075 前言:本次作业是爬取CBO中国票房2010-2019年每年 ...
- 处理Git不能上传大于100M文件问题
记录一下自己工作遇到的问题,免得下次再遇到了还到处网上查资料解决. 自己的项目的版本控制用的是Git,代码仓库在github托管.项目里用到了百度导航SDK,由于百度导航SDK有了新版本,于是就更新到 ...