小白,入门中,不足其指正。刚刚接触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)

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;
  • 结果比较
运行环境:
OS: Windows 10-64bit
IDE: codeblocks 13.12 with g++
CPU: i3
内存: 4GB
 
运行结果:

classic C style operator[]

0.00136458
Mat.at<type>(i,j) 0.00498963

从结果可以看出,指针操作明显更高效,这也就是为什么opencv-tutorials中把它称为the effective way的原因。但是,指针操作有危险性,所以很多人还是原因用Mat.at的方法。

Mat中两种像素遍历方法比较的更多相关文章

  1. Python中两种处理错误方法的比较

    我所说的处理错误的方法,其实是try:,except和raise这两种. 首先抛出一个实例, dictt={'a':1,'b':2,'c':3} try: if dictt['d']>1: #字 ...

  2. UWP开发中两种网络图片缓存方法

    通常情况下,我们的程序需要从服务器读取图片,但如果需要不止一次读取某一张图片的话,就需要做本地缓存了,这样既为用户省一点流量,又能显得你的APP很快. 假如你已经知道了某一张图片的地址,那么第一件事就 ...

  3. Cesium 中两种添加 model 方法的区别

    概述 Cesium 中包含两种添加 model 的方法,分别为: 通过 viewer.entities.add() 函数添加 通过 viewer.scene.primitives.add() 函数添加 ...

  4. python中两种拷贝目录方法的比较

    首先是用python自己的api: shutil.copytree('./build/tested/doc', './build/tested/build/doc') 优点是改变平台时不需要修改代码, ...

  5. JAVA 中两种判断输入的是否是数字的方法__正则化_

    JAVA 中两种判断输入的是否是数字的方法 package t0806; import java.io.*; import java.util.regex.*; public class zhengz ...

  6. JavaScript 中的12种循环遍历方法

    原文:JavaScript 中的12种循环遍历方法 题目:请介绍 JavaScript 中有哪些循环和遍历的方法,说说它们的应用场景和优缺点? 1.for 循环 let arr = [1,2,3];f ...

  7. jsp中两种include的区别【转】

    引用文章:http://www.ibm.com/developerworks/cn/java/j-jsp04293/ http://www.cnblogs.com/lazycoding/archive ...

  8. OC中两种单例实现方式

    OC中两种单例实现方式 写在前面 前两天探索了一下C++ 的单例,领悟深刻了许多.今天来看看OC中的单例又是怎么回事.查看相关资料,发现在OC中一般有两种实现单例的方式,一种方式是跟C++ 中类似的常 ...

  9. 关于js中两种定时器的设置及清除(转载)

    1.JS中的定时器有两种: window.setTimeout([function],[interval]) 设置一个定时器,并且设定了一个等待的时间[interval],当到达时间后,执行对应的方法 ...

随机推荐

  1. ipmitool命令详解

    基础命令学习目录首页 原文链接:https://www.cnblogs.com/EricDing/p/8995263.html [root@localhost ~]# yum install -y i ...

  2. lspci命令详解

    基础命令学习目录首页 最近经常用到 lspci -nn | grep Eth 命令,需要学习下PCI总线,找到一篇文章,虽然也是转载,但写的较清晰,再次转载下. http://blog.csdn.ne ...

  3. react-native 常规操作

    1.  关闭xcode打开模拟器的快捷键 , 等常规操作 https://www.jianshu.com/p/f6723f3406b7

  4. (第七周)评论alpha发布

    本人所在组:奋斗吧兄弟 按课上展示组的顺序对其他组进行点评: 1.  新蜂 项目:游戏俄罗斯方块 界面完善,已经实现了游戏的基本功能.可以对图形进行变换形状,进行位置移动,可以加快下落的速度,并对一整 ...

  5. 结对编程-->总结报告

    项目github地址 PSP时间表格 结对编程中关于Information Hiding, Interface Design, Loose Coupling原则的使用 Information Hidi ...

  6. java(系统)实战1

    在简单学习了java的布局和一些界面的绘制方法后,我便开始有了跟着视频和书本的知识学做一个简单的餐饮系统,才能激发自己的编程和不断巩固知识. 我简单说明一下本次做的系统很普通但具有实用性,是通过jav ...

  7. js dom学习

    创建dom元素 var oLi = document.creteElement('li'); //创建livar aLi = oUl.getElementsByTagName('li');oLi.in ...

  8. [转帖]HTTPS系列干货(一):HTTPS 原理详解

    HTTPS系列干货(一):HTTPS 原理详解 https://tech.upyun.com/article/192/HTTPS%E7%B3%BB%E5%88%97%E5%B9%B2%E8%B4%A7 ...

  9. 2013杭州网赛 1001 hdu 4738 Caocao's Bridges(双连通分量割边/桥)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4738 题意:有n座岛和m条桥,每条桥上有w个兵守着,现在要派不少于守桥的士兵数的人去炸桥,只能炸一条桥 ...

  10. Nginx - request_time和upstream_response_time的区别

    request_time 官网描述:request processing time in seconds with a milliseconds resolution; time elapsed be ...