翻译:陈之炎
校对:顾伟嵩本文约3200字,建议阅读7分钟本教程的目标是展示如何使用OpenCV的parallel_for_框架轻松实现代码并行化。

目标

本教程的目标是展示如何使用OpenCV的parallel_for_框架轻松实现代码并行化。为了说明这个概念,我们将编写一个程序,利用几乎所有的CPU负载来绘制Mandelbrot集合。完整的教程代码可见原文。如果想了解更多关于多线程的信息,请参考本教程中提及的参考书或课程。

预备条件

首先是搭建OpenCV并行框架。在OpenCV3.2中,可以按此顺序使用以下并行框架:

1. 英特尔线程构建模块(第三方库,应该明确启用)

2. C =并行C / C ++编程语言扩展(第三方库,应该明确启用)

3. OpenMP(集成的编译器,应明确启用)

4. APPLE GCD(系统层面,自动使用(仅适用APPLE))

5. Windows RT并发(系统层面,自动使用(仅适用Windows RT))

6. Windows并发(部分运行时间,自动使用(仅适用Windows  -  MSVC ++> = 10))

7. Pthreads (如果适用)

正如前面所述,OpenCV库可以使用多个并行框架。有些并行库为第三方提供的库,建立时应明确地用CMake(如TBB,C =)启用,其余均为自动可用的平台(例如APPLE GCD),但是,无论是直接使用并行框架还是利用CMake启用并行框架并重建库,首先要做的是启用并行框架。

第二个(弱)预备条件与任务相关,因为不是所有任务的计算都可以/适合以并行方式来运行。为了尽量保持简单,可以将任务分解为与存储器无关的多个元素,从而使其更加容易实现并行化。在计算机视觉处理过程中,由于大多数时间里一个像素的处理不依赖于其它像素的状态,所以往往更加容易实现并行化。

简单的示例:绘制Mandelbrot集合

这个例子中将展示如何绘制Mandelbrot集合,将普通的顺序代码实现并行化计算。

理论

Mandelbrot集合的名称是数学家阿德里恩·多迪(Adrien Douady)为悼念数学家蒙德布罗特(Mandelbrot),以他的名字来命名的。它在数学界之外,作为分形类的一个例子,在图像表示领域非常著名。Mandelbrot集合为一组自相似的重复图案在不同尺度下重复显示结果。为了进一步深入介绍,可以参考Wikipedia article。在这里,仅介绍利用公式绘制Mandelbrot集合(选自维基百科的文章)。

Mandelbrot集合是在复平面中一组值C沿着0轨迹的二次迭代映射的边界。

即,复数c作为Mandelbrot集的一部分,从 Z0 = 0开始重复进行迭代,当n趋近于无穷大时,Zn的绝对值的边界值,它可以表示为:

伪代码

生成Mandelbrot集合的简单的算法被称为“逃逸时间算法”。为渲染图像中的每个像素,根据复数值是否在边界范围之内,利用递推关系进行测试。经过数次迭代之后,不属于Mandelbrot集合的像素将快速逃逸,留下来的将是属于Mandelbrot集合的像素。随着计算时间的增加,迭代后的高阶值将产生一个更详细的图像。在这里使用实现“逃逸”所需要的迭代次数来描绘图像中的像素值。

将伪代码和理论相关联之后,得到:

在上图中,复数的实部在x轴上,复数的虚部在y轴上。通过对图形局部放大,可以看到整个形状均重复可见。

代码实现

逃逸时间算法的实现

在这里,我们使用了std::complex模板类来表示复数。利用这个函数来进行测试,以检查像素是否在集合之中,并返回“逃逸”迭代。

顺序的Mandelbrot实现

在此程序中,通过依次遍历渲染图像中的像素来进行测试,以检查像素是否属于Mandelbrot集合。

需要做的另一件事是把像素坐标转换Mandelbrot集合空间:

最后,将灰度值分配给像素,使用以下规则:

  • 当迭代次数达到最大值时,像素为黑色(假定像素在Mandelbrot集合中);

  • 否则根据逃脱“逃逸迭代”和缩放尺度,为像素分配一个灰度值,以适应灰度范围。

使用线性缩放转换不足以感知的灰度变化。为了克服这个问题,使用一个平方根转换来提升感知度(引用了Jeremy D. Frens博客中的内容): 

绿色曲线对应于简单的线性缩放转换,蓝色曲线对应于平方根转换,可以从中观察到的最低值如何沿着斜坡正向上升。

并行Mandelbrot实现

在顺序的Mandelbrot实现中,每个像素被独立计算。为了优化计算,我们可以利用现代处理器的多核架构并行执行多个像素的计算,利用OpenCV的CV :: parallel_for_框架可以轻松实现。

第一件事是声明一个继承CV :: ParallelLoopBody的自定义类,覆盖virtual void operator ()(const cv::Range& range) const。

operator ()表示将通过一个独立的线程来处理像素的子集,这种拆分是自动完成的,以平均分配计算负荷,为此必须将像素索引坐标转换成2D [行,列]坐标。还要注意的是,必须保持图像的mat对象引用值,以便能够适时地对图像进行修改。

调用并行执行程序:

在这里,range表示将要执行的操作总数,即图像中的像素总数。使用CV :: setNumThreads设置线程数,还可以使用CV :: parallel_for_中的 nstripes参数指定拆分的数量CV :: parallel_for_。例如,如果处理器有4个线程,则设置CV :: setNumThreads(2)或者设置nstripes = 2应该是一样的,默认情况下它会使用所有可用的处理器线程,但拆分后只有两个线程。

为了简化并行的实现,C ++ 11标准删除了ParallelMandelbrot类,采用lambda表达式代替它:

运行结果

可以在原文找到完整的教程源代码,并行实现的性能取决于CPU的种型。例如,在4核/ 8线程的CPU上,可以提速6.9倍左右。如果要问,为什么达不到8倍速,其中有很多因素;主要原因是由于:

  • 创建和管理线程的额外开销;

  • 并行运行的后台进程;

  • 带2个逻辑线程的4硬件核与8硬件核之间是有区别的。

由教程代码生成的输出图像(可以对代码进行修改,以使用更多次的迭代,根据逃逸迭代次数来分配像素颜色,并使用调色板以获得更美的图像):

Mandelbrot集合XMIN = -2.1,XMAX = 0.6,YMIN = -1.2,YMAX = 1.2,maxIterations = 500

原文链接:

https://docs.opencv.org/4.5.2/d7/dff/tutorial_how_to_use_OpenCV_parallel_for_.html

往期回顾:

独家|OpenCV 1.1 Mat - 基本图像容器(附链接)

独家|OpenCV 1.2 如何用OpenCV扫描图像、查找表和测量时间(附链接)

独家|OpenCV 1.3 矩阵的掩膜操作(附链接)

独家|OpenCV 1.4 对图像的操作

独家|OpenCV 1.5 利用OpenCV叠加(混合)两幅图像

独家|OpenCV 1.6 改变图像的对比度和亮度!

独家|OpenCV 1.7 离散傅里叶变换

独家|OpenCV1.8 使用XML和YAML文件实现文件的输入/输出

编辑:王菁

校对:汪雨晴

译者简介

陈之炎,北京交通大学通信与控制工程专业毕业,获得工学硕士学位,历任长城计算机软件与系统公司工程师,大唐微电子公司工程师,现任北京吾译超群科技有限公司技术支持。目前从事智能化翻译教学系统的运营和维护,在人工智能深度学习和自然语言处理(NLP)方面积累有一定的经验。业余时间喜爱翻译创作,翻译作品主要有:IEC-ISO 7816、伊拉克石油工程项目、新财税主义宣言等等,其中中译英作品“新财税主义宣言”在GLOBAL TIMES正式发表。能够利用业余时间加入到THU 数据派平台的翻译志愿者小组,希望能和大家一起交流分享,共同进步

翻译组招募信息

工作内容:需要一颗细致的心,将选取好的外文文章翻译成流畅的中文。如果你是数据科学/统计学/计算机类的留学生,或在海外从事相关工作,或对自己外语水平有信心的朋友欢迎加入翻译小组。

你能得到:定期的翻译培训提高志愿者的翻译水平,提高对于数据科学前沿的认知,海外的朋友可以和国内技术应用发展保持联系,THU数据派产学研的背景为志愿者带来好的发展机遇。

其他福利:来自于名企的数据科学工作者,北大清华以及海外等名校学生他们都将成为你在翻译小组的伙伴。

点击文末“阅读原文”加入数据派团队~

转载须知

如需转载,请在开篇显著位置注明作者和出处(转自:数据派ID:DatapiTHU),并在文章结尾放置数据派醒目二维码。有原创标识文章,请发送【文章名称-待授权公众号名称及ID】至联系邮箱,申请白名单授权并按要求编辑。

发布后请将链接反馈至联系邮箱(见下方)。未经许可的转载以及改编者,我们将依法追究其法律责任。

点击“阅读原文”拥抱组织

独家|OpenCV1.9 如何利用OpenCV的parallel_for_并行化代码(附代码)相关推荐

  1. 【CV】使用OpenCV进行消失点检测(附代码)

    简介 消失点的定义:消失点是透视图图像平面上的一个点,三维空间中相互平行的线的二维透视投影(或图形)似乎会聚.图像中的所有东西似乎都汇聚在一个点上,这个点被称为消失点.如上图所示,右侧图像中心的&qu ...

  2. 使用OpenCV进行消失点检测(附代码)

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 简介 消失点的定义:消失点是透视图图像平面上的一个点,三维空间中相 ...

  3. 独家 | 用pandas-profiling做出更好的探索性数据分析(附代码)

    作者:Thomas Gey 翻译:廖倩颖 校对:和中华 本文约2300字,建议阅读5分钟. 探索性数据分析已失势,Pandas-profiling万岁!用更省力的办法完美呈现你的数据. 标签:机器学习 ...

  4. 独家 | 秘籍:10个Python字符串处理技巧(附代码)

    作者:马修·梅奥 翻译:陈之炎 校对:和中华 本文约1600字,建议阅读7分钟. 本文为你介绍利用Python处理字符串的一些基本操作. 在探寻文本分析途径时却不知从何下手,该怎么办?那么可以通过这个 ...

  5. 独家 | 手把手教你组织数据科学项目!(附代码)

    作者:kdnuggets 翻译:和中华 校对:丁楠雅 本文约4200字,建议阅读10分钟. 本文介绍了一个工具可以帮助迅速构建一个标准但灵活的数据科学项目结构,便于实施和分享数据科学工作. 由Driv ...

  6. dataframe 如何选中某列的一行_PySpark和SparkSQL基础:如何利用Python编程执行Spark(附代码)

    作者:Pinar Ersoy 翻译:孙韬淳 校对:陈振东 本文约2500字,建议阅读10分钟 本文通过介绍Apache Spark在Python中的应用来讲解如何利用PySpark包执行常用函数来进行 ...

  7. 使用PyTorch+OpenCV进行人脸识别(附代码演练)

    人脸识别是一种用于从图像或视频中识别人脸的系统.它在许多应用程序和垂直行业中很有用.如今,我们看到这项技术可帮助新闻机构在重大事件报道中识别名人,为移动应用程序提供二次身份验证,为媒体和娱乐公司自动索 ...

  8. 利用yaml定义卷积网络【附代码】

    在平常看一些卷积神经网络的时候,大多数都是直接通过写一个Model类来定义的,这样写的代码其实是比较好懂的,特别是在魔改网络的时候也很方便.然后也有一些会通过cfg配置文件进行模型的定义.在yolov ...

  9. 独家 | 指南:不平衡分类的成本敏感决策树(附代码链接)

    作者:Jason Brownlee 翻译:陈超 校对:冯羽 本文约3500字,建议阅读10+分钟 本文介绍了不平衡分类中的成本敏感决策树算法. 决策树算法对平衡分类是有效的,但在不平衡数据集上却表现不 ...

最新文章

  1. 支付宝支付 第十集:支付回调
  2. Java中的数组怎么弄随机数_Java – 如何从值数组中创建随机数
  3. linux rpm包,安装路径查看及改变rpm包默认安装路径
  4. 字更大、页面更简单 淘宝长辈模式正式上线
  5. 【Mybatis】Mybatis三大组件之ResultSetHandler
  6. 银行转账java mysql_一个银行转账业务模型分析:大魏Java记5-7
  7. Scratch案例——放烟花
  8. 【STM32F429的DSP教程】第8章 DSP定点数和浮点数(重要)
  9. USB数据采集卡 USB1208LS、1608FS DAQami 软件功能有哪些
  10. 数组重新定义key值,去重,排序
  11. 指令引用的内存不能为written怎么解决
  12. 我们都是穷人甲乙丙丁
  13. 怎样才能成为一名有创造力的领导者?
  14. U盘安装苹果系统教程,菜鸟一步一步也能成大牛
  15. 记录一下我在lubuntu里面用到的工具
  16. 什么是多进程-多线程-多协程 ----进程和多进程
  17. 关于我如何阅读源码这件事...
  18. 迁移confluence
  19. 如何用js实现简单的页面html动态加载(“看更多“/页面折叠功能)
  20. 《思考的技术》总结(一)

热门文章

  1. 输入一行字符,判断单词数
  2. 【c语言】蓝桥杯算法训练 连接字符串
  3. matlab仿真谱间干扰,内外分解和谱分解问题解析计算及其MATLAB仿真.pdf
  4. jvm对象从新生代到老年代_深入理解jvm内存模型以及gc原理
  5. LR监测windows资源一般监测哪几个项?
  6. nginx三大功能(之二负载均衡)
  7. 使用Ptrace跟踪进程收到的异常信号(信号SIGTRAP是通过traceme后wait得到的)
  8. Silverlight HLSL实现背景滚动
  9. 高通驱动9008安装_赛多利斯Sartorius-ambr? 250 高通量灌注培养系统
  10. 使用inetaddress测试目标可达性_白盒测试工具―Winams介绍