OpenCV 从2.4.3开始加入了并行计算的函数parallel_for和parallel_for_(更准确地讲,parallel_for以前就存在于tbb模块中,但是OpenCV官网将其列在2.4.3.的New Features中,应该是重新改写过的)。

2.4.3中自带的calcOpticalFlowPyrLK函数也用parallel_for重写过了,之前我一直认为parallel_for就是用来并行计算的,之前也自己写了一些用parallel_for实现的算法。直到今天在opencv官网中看到别人的提问,才发现parallel_for实际上是serial loop,而parallel_for_才是parallel loop(OpenCV官网answer)。

为了比较for循环,parallel_for和parallel_for_ 三者的差异,下面做了一个简单的测试,对一个Mat中所有的元素(按列为单位)做立方操作。

Code

test.hpp

/**@ Test parallel_for and parallel_for_
/**@ Author: chouclee
/**@ 03/17/2013*/
#include <opencv2/core/internal.hpp>
namespace cv
{
namespace test
{class parallelTestBody : public ParallelLoopBody//参考官方给出的answer,构造一个并行的循环体类{public:parallelTestBody(Mat& _src)//class constructor{src = &_src;}void operator()(const Range& range) const//重载操作符(){Mat& srcMat = *src;int stepSrc = (int)(srcMat.step/srcMat.elemSize1());//获取每一行的元素总个数(相当于cols*channels,等同于step1)for (int colIdx = range.start; colIdx < range.end; ++colIdx){float* pData = (float*)srcMat.col(colIdx).data;for (int i = 0; i < srcMat.rows; ++i)pData[i*stepSrc] = std::pow(pData[i*stepSrc],3);}    }private:Mat* src;};struct parallelTestInvoker//构造一个供parallel_for使用的循环结构体{parallelTestInvoker(Mat& _src)//struct constructor{src = &_src;}void operator()(const BlockedRange& range) const//使用BlockedRange需要包含opencv2/core/internal.hpp{Mat& srcMat = *src;int stepSrc = (int)(srcMat.step/srcMat.elemSize1());for (int colIdx = range.begin(); colIdx < range.end(); ++colIdx){float* pData = (float*)srcMat.col(colIdx).data;for (int i = 0; i < srcMat.rows; ++i)pData[i*stepSrc] = std::pow(pData[i*stepSrc],3);}}Mat* src;};
}//namesapce test
void parallelTestWithFor(InputArray _src)//'for' loop
{CV_Assert(_src.kind() == _InputArray::MAT);Mat src = _src.getMat();CV_Assert(src.isContinuous());int stepSrc = (int)(src.step/src.elemSize1());for (int x = 0; x < src.cols; ++x){float* pData = (float*)src.col(x).data;for (int y = 0; y < src.rows; ++y)pData[y*stepSrc] = std::pow(pData[y*stepSrc], 3);}
};void parallelTestWithParallel_for(InputArray _src)//'parallel_for' loop
{CV_Assert(_src.kind() == _InputArray::MAT);Mat src = _src.getMat();int totalCols = src.cols;typedef test::parallelTestInvoker parallelTestInvoker;parallel_for(BlockedRange(0, totalCols), parallelTestInvoker(src));
};void parallelTestWithParallel_for_(InputArray _src)//'parallel_for_' loop
{CV_Assert(_src.kind() == _InputArray::MAT);Mat src = _src.getMat();int totalCols = src.cols;typedef test::parallelTestBody parallelTestBody;parallel_for_(Range(0, totalCols), parallelTestBody(src));
};
}//namespace cv

main.cpp

/**@ Test parallel_for and parallel_for_
/**@ Author: chouclee
/**@ 03/17/2013*/
#include <opencv2/opencv.hpp>
#include <time.h>
#include "test.hpp"
using namespace cv;
using namespace std;int main(int argc, char* argv[])
{Mat testInput = Mat::ones(40,400000, CV_32F);clock_t start, stop;start = clock();parallelTestWithFor(testInput);stop = clock();cout<<"Running time using \'for\':"<<(double)(stop - start)/CLOCKS_PER_SEC*1000<<"ms"<<endl;start = clock();parallelTestWithParallel_for(testInput);stop = clock();cout<<"Running time using \'parallel_for\':"<<(double)(stop - start)/CLOCKS_PER_SEC*1000<<"ms"<<endl;start = clock();parallelTestWithParallel_for_(testInput);stop = clock();cout<<"Running time using \'parallel_for_\':"<<(double)(stop - start)/CLOCKS_PER_SEC*1000<<"ms"<<endl;system("pause");
}
Result

输入为400000*40时,结果如下:
Debug模式
Running time using 'for': 1376ms
Running time using 'parallel_for': 1316ms
Running time using 'parallel_for_': 553ms
Release模式
Running time using 'for': 463ms
Running time using 'parallel_for': 475ms
Running time using 'parallel_for_': 301ms

输入改为40*400000
Debug模式
Running time using 'for': 1005ms
Running time using 'parallel_for': 1013ms
Running time using 'parallel_for_': 526ms
Release模式
Running time using 'for': 105ms
Running time using 'parallel_for': 106ms
Running time using 'parallel_for_': 81ms

输入改为4000*4000
Debug模式
Running time using 'for': 1138ms
Running time using 'parallel_for': 1136ms
Running time using 'parallel_for_': 411ms
Release模式
Running time using 'for': 234ms
Running time using 'parallel_for': 239ms
Running time using 'parallel_for_': 130ms

大多数情况下,parallel_for比for循环慢那么一丁丁点儿,有时甚至会比for循环快一些,总体上两者差不多,parallel_for_一直都是最快的。但上面的代码只是做测试使用(因此强制按列进行操作),实际上,像上面这种简单的操作,直接对Mat使用for循环和指针递增操作,只需要几十毫秒。但是,对于复杂算法,比如光流或之类的,使用parallel_for(虽然不是并行操作,但代码简洁易于维护,且速度和for循环差不多)或者parallel_for_将是不错的选择。

Reference:

http://answers.opencv.org/question/3730/how-to-use-parallel_for/

OpenCV中parallel_for 和 parallel_for_学习笔记相关推荐

  1. 数据库LINQ TO SQL在Silverlight中的应用(WCF)------学习笔记(一)

    数据库LINQ TO SQL在Silverlight中的应用(WCF)------学习笔记(一) 步骤: 1. 创建SILVERLIGHT应用程序 2. 创建LINQ TO SQL [注意序列化的问题 ...

  2. C++ 中 参数包 (typename ...) 学习笔记

    C++ 中 参数包 (typename -) 学习笔记 本文所属地址 https://www.lucien.ink 起因 突然好奇 STL 的 std::tuple 是怎么实现不定参数的,遂搜了搜,发 ...

  3. web前端分享HTML5中的nav标签学习笔记

    好程序员web前端分享HTML5中的nav标签学习笔记,nav标签全称navigation,顾名思义,是导航的意思.根据HTML5的相关标准定义如下: "A section of a pag ...

  4. 用opencv实现目标追踪的学习笔记——camshift

    小白的学习笔记--opencv camshift -基础:零c++基础,零opencv基础,简单C语言基础,略知数字图像处理知识 -工具:VS2015+opencv 2.4.13 -sample: E ...

  5. python怎么测试opencv安装是否成功_学习笔记:自己编译安装OpenCV+测试opencv安装是否成功...

    跟着猿人学python,我的学习笔记.本次的配置在ubuntu中成功安装了opencv,并通过以下方法测试成功了.现将具体的安装及测试过程整理出来分享给大家. 1. 安装编译依赖的软件包 # 安装读写 ...

  6. opencv 叠加文字_opencv3.1学习笔记(8) 绘制形状与文字

    绘制形状比较简单,基本上没啥子好说的,见代码. 演示代码:#include #include using namespace std; using namespace cv; Mat bgImage; ...

  7. linux rcs文件中的ip,linux学习笔记之diff和patch命令

    关键字:Linux 学习笔记 运维 系统 命令 一.命令的功能 diff命令的功能为逐行比较两个文本文件,列出其不同之处.可是做成diff记录也就是补丁. patch就是利用diff制作的补丁来打到文 ...

  8. linux中内核中machine_desc,Linux-内核-学习笔记(13):移植三星官方内核

    Linux-内核-学习笔记(13):移植三星官方内核 一.移植前的准备 当拿到源代码时,首先要在window下利用SourceInsight创建一个工程,并将uboot源代码加载到SI中,方便修改和查 ...

  9. textarea中插入标签_HTMLCSS学习笔记(二)-- HTML表单标签

    表单 1 : 表单标签 <form></form> 属性 : action = '接口地址' method = 'get / post' name = '表单名称' 2 : 表 ...

最新文章

  1. 双表查询java代码_什么是JDBC?Java数据库连接性简介
  2. android 添加附件功能,Android实现带附件的邮件发送功能
  3. java 获取聚合vo_NC57聚合VO写法
  4. python 二叉树中所有距离为k的节点_leetcode 二叉树中所有距离为 K 的结点
  5. 阿里云服务器ubuntu14.04安装Redis
  6. 在redhat9中交叉编译nano-X nxlib和fltk
  7. Harris算子的运用 用于图像配准
  8. Chrome浏览器插件安装位置
  9. css段落缩进_如何缩进Google文档中的段落
  10. spring-junit4_基于Spring的应用程序-迁移到Junit 5
  11. Flowable 数据库表结构 ACT_GE_PROPERTY
  12. 见微知著,构“见”未来
  13. axios_的其他方式发送请求_使用axios.request .get .delete .post .put 等方法发送请求---axios工作笔记005
  14. 一次解决Linux内核内存泄漏实战全过程
  15. 解决idea中找不到程序包和找不到符号的问题
  16. 相机模型与标定(三)--张正友标定
  17. 三步解决error: Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build Tools“
  18. 改进YOLOv5!GSConv+Slim Neck进一步提升YOLOv5性能!
  19. 计算机sci 四区,sci四区什么水平
  20. phpmywind 导航函数详解整理中……

热门文章

  1. RTC实时时钟(STM32)
  2. 华为机试 计算加减乘除数学表达式的结果
  3. 在packet tracer模拟器中创建拓扑并重置密码
  4. 智能座舱的交互革命,高算力AI芯片赋能全时全域交互体验
  5. 38Khz红外遥控发射
  6. Nios ii 实战篇--- DDR2
  7. oTree学习教程(六)Multiplayer games
  8. Cubase独占声卡问题
  9. vue端计算大文件的sha256
  10. 关于Flash 页游中的那些优化1