一、提高OpenCV的运算速度,有以下几种方法:

1、利用x86转为x64提速,可以提高1倍的速度

2、多线程的openmp或Intel TBB提速,将cpu的利用率从20%多提高到100%

3、利用GPU提速,至少可以提高5~10倍的运算速度

二、openmp

Home - OpenMPhttps://www.openmp.org/

Specifications - OpenMPhttps://www.openmp.org/specifications/很多主流的编译环境都内置了OpenMP。VS 版本不低于2015,都支持 OpenMP。在VS中启用OpenMPhttps://docs.microsoft.com/zh-cn/cpp/parallel/openmp/openmp-in-visual-cpp很简单,在项目上右键->属性->配置属性->C/C++->语言->OpenMP支持,选择是”即可。这实际上使用了编译选项/openmp。但是学习和使用openmp,应该考虑使用官方的高版本,最好不要使用Visual Studio自带的,因为VS2017只支持到OpenMP2.0版本。

openmp3.0中的task(任务,可动态配置)在多线程中是很重要的。
openmp4.0中的simd(向量化,单指令多数据),在密集性计算优化中很有用,比如挖矿类型的计算。target(异构计算相关系列指令),可以直接在openmp中使用gpgpu并行。
openmp4.5和5.0加入了很多对simd及gpu支持的深化内容。

举例:

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#pragma comment(lib,"opencv_core2410d.lib")
#pragma comment(lib,"opencv_highgui2410d.lib")
#pragma comment(lib,"opencv_imgproc2410d.lib")void EdgeOpenMP(IplImage *src,IplImage *dst,int thresh)
{int height    = src->height;int width     = src->width;int step      = src->widthStep;uchar *data1  = (uchar *)src->imageData;uchar *data2  = (uchar *)dst->imageData;int i = step;#pragma omp parallel forfor(i=step+1;i<height*width;i++){if(abs(data1[i]-data1[i-1])>thresh || abs(data1[i]-data1[i-step])>thresh)data2[i]=255;/* 对于单通道,前后两帧差分大于门限或者对于多通道前后两帧的一个指标差分大于门限,则视为边缘*/elsedata2[i]=0;}
}void Edge(IplImage *src,IplImage *dst,int thresh)
{int height    = src->height;int width     = src->width;int step      = src->widthStep;uchar *data1      = (uchar *)src->imageData;uchar *data2      = (uchar *)dst->imageData;int i = step;for(i=step+1;i<height*width;i++){if(abs(data1[i]-data1[i-1])>thresh || abs(data1[i]-data1[i-step])>thresh)data2[i]=255;elsedata2[i]=0;}
}int main()
{char filename[512];IplImage *src,*edge1,*edge2;puts("File name:");gets(filename);src = cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE );edge1=cvCloneImage(src);edge2=cvCloneImage(src);cvNamedWindow("src", CV_WINDOW_AUTOSIZE);cvMoveWindow("src", 100, 100);cvShowImage( "src", src);cvNamedWindow("Edge", CV_WINDOW_AUTOSIZE);cvMoveWindow("Edge", 200, 100);cvNamedWindow("EdgeOpenMP", CV_WINDOW_AUTOSIZE);cvMoveWindow("EdgeOpenMP", 300, 100);/* 以上都是准备一些窗口和图形基本数据 */int tekrar=100;//运行次数int thresh=30;double start, end,t1, t2;/* 计算没有使用OpenMP优化的时间 */start= (double)cvGetTickCount();//记下开始的时钟计数,以便计算函数或用户代码执行时间for(int i=0;i<tekrar;i++)Edge(src,edge1,thresh);end= (double)cvGetTickCount();//记下结束的时钟计数t1= (end-start)/((double)cvGetTickFrequency()*1000.);//计算运行时间,以毫秒为单位printf( "Run time without OpenMP = %g ms\n", t1 );/* 计算使用了OpenMP优化的时间 */start= (double)cvGetTickCount();for(int i=0;i<tekrar;i++)EdgeOpenMP(src,edge2,thresh);end= (double)cvGetTickCount();t2= (end-start)/((double)cvGetTickFrequency()*1000.);printf( "Run time with OpenMP = %g ms\n", t2 );printf( "Performance ratio (%%) = %% %.1f \n", 100*(t1/t2-1) );cvShowImage( "Edge", edge1);cvShowImage( "EdgeOpenMP", edge2);cvWaitKey();cvDestroyWindow("Edge");cvDestroyWindow("EdgeOpenMP");cvReleaseImage(&src);cvReleaseImage(&edge1);cvReleaseImage(&edge2);
}

参考文献:

《多核异构并行计算 OpenMP 4.5 C/C++篇》语法介绍比较详细,雷洪编著的。

OpenMP并行计算入门案例https://blog.csdn.net/tlqtangok/article/details/95875455
关于使用opencv的提速(二)(多线程问题,openMP)https://blog.csdn.net/wangzhebupt/article/details/22743515

OpenMP简介https://blog.csdn.net/longji/article/details/95076143

三、PPL

微软自家的并行库,ppl只能在windows上用不能跨平台,tbb能跨平台,但是受限于原始设计,tbb的task比较弱没有ppl的强大。

concurrency::parallel_for(0, num, [&](int i) { //索引[0, num)

});

其中,索引[0, num)的意思是

for (int i = 0; i < num; i++)

注意,0和num的类型必须是int型。因为int i。

并发运行时 | Microsoft Docs详细了解:并发运行时https://docs.microsoft.com/zh-cn/cpp/parallel/concrt/concurrency-runtime

#include <ppl.h> //concurrency::parallel_forconcurrency::parallel_for(0, szSize.height, [&](int i) { //y方向,索引[0,szSize.height)short *pSdx = (short *)(Sdx.data + Sdx.step * (i));short *pSdy = (short *)(Sdy.data + Sdy.step * (i));double dSx = 0, dSy = 0;double gradMag = 0;for (int j = 0; j < szSize.width; j++) //x方向{dSx = pSdx[j]; //X derivative of Source imagedSy = pSdy[j]; //Y derivative of Source imagegradMag = sqrt((dSx * dSx) + (dSy * dSy)); //Magnitude = Sqrt(dx^2 +dy^2)if (gradMag != 0) //hande divide by zero{matGradMag[i][j] = 1 / gradMag; //1/Sqrt(dx^2 +dy^2)}else{matGradMag[i][j] = 0;}}});

四、TBB --- Threading Building Blocks

Advanced HPC Threading: Intel® oneAPI Threading Building Blockshttps://www.intel.com/content/www/us/en/developer/tools/oneapi/onetbb.html

https://github.com/oneapi-src/oneTBBhttps://github.com/oneapi-src/oneTBB

按照目前网上的讨论,TBB风头要盖过openMP,比如openCV过去是使用openMP的,但从2.3版本开始抛弃openMP,转向TBB。Opencv源码需要自己编译,cmake选项勾上TBB。Add option WITH_TBB=ON when building opencv。

举例:

// A very raw example of using tbb's thread
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/video/video.hpp>
#include <opencv2/highgui.hpp>
#include <tbb/tbb.h>
#include <iostream>using namespace std;
using namespace cv;
using namespace tbb;int main(int argc, char* argv[])
{int TBB_THREADS = 3;task_scheduler_init init(TBB_THREADS);Mat im1 = imread(argv[1]);Mat imGray;if (im1.data == nullptr){cout << "Error while reading file " << argv[1];return 1;}imshow("Input image", im1);cvtColor(im1, imGray, CV_RGB2GRAY);Mat im3, im4;tbb_thread th1([&imGray, &im3]() // in fact, you can do this with C++ thread{int windowSize = 5; // starting threshold valueint constant = 5; // starting constant valueadaptiveThreshold(imGray, im3, 255,CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY,windowSize, constant);});tbb_thread th2([&imGray, &im4](){cv::GaussianBlur(imGray, im4, cv::Size(3, 3), 5.0f);});th1.join();th2.join();imshow("Grayscale image", imGray);imshow("Adaptive thresholding", im3);imshow("Gaussian blur", im4);cvWaitKey(0);return 0;
}

参考文献:

OpenCV加速与优化,让代码执行速度飞起来https://cloud.tencent.com/developer/article/1536447

https://www.theimpossiblecode.com/blog/faster-opencv-smiles-tbb/https://www.theimpossiblecode.com/blog/faster-opencv-smiles-tbb/

五、GPU

1、主流的显卡是NVIDIA和ATI两种,简称N卡和A卡;而opencv的gpu单指N卡显卡模块,而且只支持一部分。

N卡支持的型号一览表:

CUDA GPUs | NVIDIA Developerhttps://developer.nvidia.com/cuda-gpus

Windows开始菜单--运行--输入dxdiag--显示,可以看到自己电脑的显卡型号。

笔者的显卡需要查阅网页的字段:CUDA-Enabled GeForce and TITAN Products,型号是GeForce GT 630,支持!

cuda源码下载:

CUDA Toolkit | NVIDIA Developerhttps://developer.nvidia.com/cuda-toolkit

Index of /compute/cuda/opensourcehttps://developer.download.nvidia.cn/compute/cuda/opensource/

如果你是ATI显卡,或者用的不是电脑,又想GPU加速怎么办呢?那就让OpenCV和OpenCL结合起来,有跨平台的作用,可以应用到ATI显卡上。

2、CUDA vs OpenCL

OpenCL: Open Computing Language,开放计算语言。

OpenCL Overview - The Khronos Group Inchttps://www.khronos.org/opencl/
OpenCL和CUDA是两种异构计算(此异构平台可由CPU,GPU或其他类型的处理器组成。)的编程模型。

CUDA只支持NVIDIA自家的GPU。OpenCL最早是由Apple提出,后来交给了Khronos这个开放标准组织。

CUDA C语言与OpenCL的定位不同,或者说是使用人群不同。CUDA C是一种高级语言,那些对硬件了解不多的非专业人士也能轻松上手;而OpenCL则是针对硬件的应用程序开发接口,它能给程序员更多对硬件的控制权,相应的上手及开发会比较难一些。

从很多方面来看,CUDA和OpenCL的关系都和DirectX与OpenGL的关系很相像。如同DirectX和OpenGL一样,CUDA和OpenCL中,前者是配备完整工具包、针对单一供应商(NVIDIA)的成熟的开发平台,后者是一个开放的标准。
虽然两者抱着相同的目标:通用并行计算。但是CUDA仅仅能够在NVIDIA的GPU硬件上运行,而OpenCL的目标是面向任何一种Massively Parallel Processor,期望能够对不同种类的硬件给出一个相同的编程模型。由于这一根本区别,二者在很多方面都存在不同:
1)开发者友好程度。CUDA在这方面显然受更多开发者青睐。原因在于其统一的开发套件(CUDA Toolkit, NVIDIA GPU Computing SDK以及NSight等等)、非常丰富的库(cuFFT, cuBLAS, cuSPARSE, cuRAND, NPP, Thrust)以及NVCC(NVIDIA的CUDA编译器)所具备的PTX(一种SSA中间表示,为不同的NVIDIA GPU设备提供一套统一的静态ISA)代码生成、离线编译等更成熟的编译器特性。相比之下,使用OpenCL进行开发,只有AMD对OpenCL的驱动相对成熟。
2)跨平台性和通用性。这一点上OpenCL占有很大优势(这也是很多National Laboratory使用OpenCL进行科学计算的最主要原因)。OpenCL支持包括ATI,NVIDIA,Intel,ARM在内的多类处理器,并能支持运行在CPU的并行代码,同时还独有Task-Parallel Execution Mode,能够更好的支持Heterogeneous Computing。这一点是仅仅支持数据级并行并仅能在NVIDIA众核处理器上运行的CUDA无法做到的。
3)市场占有率。作为一个开放标准,缺少背后公司的推动,OpenCL显然没有占据通用并行计算的主流市场。NVIDIA则凭借CUDA在科学计算、生物、金融等领域的推广牢牢把握着主流市场。再次想到OpenGL和DirectX的对比,不难发现公司推广的高效和非盈利机构/标准委员会的低效(抑或谨慎,想想C++0x)。
我接触的很多开发者(包括我本人)都认为,由于目前独立显卡市场的萎缩、新一代处理器架构(AMD的Graphics Core Next (GCN)、Intel的Sandy Bridge以及Ivy Bridge)以及新的SIMD编程模型(Intel的ISPC等)的出现,未来的通用并行计算市场会有很多不确定因素,CUDA和OpenCL都不是终点,我期待未来会有更好的并行编程模型的出现(当然也包括CUDA和OpenCL,如果它们能够持续发展下去)。

参考文献:

opencv如何利用GPU加速

CUDA和OpenCL有什么区别?

CUDA 与 OpenCL 区别

六、引申阅读之TaskCpp

https://github.com/qicosmos/TaskCppV1.1

TaskCpp是c++11开发的一个跨平台的并行task库,它的设计思路来源于微软的并行计算库ppl和intel的并行计算库tbb

(原创)发布一个c++11开发的轻量级的并行Task库TaskCpp - qicosmos(江南) - 博客园TaskCpp简介 TaskCpp是c++11开发的一个跨平台的并行task库,它的设计思路来源于微软的并行计算库ppl和intel的并行计算库tbb,关于ppl和tbb我在前面有介绍。既然已经有了这https://www.cnblogs.com/qicosmos/p/3534967.html

---

欢迎访问姊妹篇《关于实现Halcon算法加速的基础知识》

OpenCV算法加速(1)OpenMP/PPL/TTB基础知识相关推荐

  1. OpenCV算法加速的一些学习总结

    一.概述 算法加速在实际软件层面应用来说 大数据和复杂计算的过程中 算法优化,指降低算法计算复杂度,设计新算法快速求解,比如Hungarian匹配算法.或牺牲一些内存,预计算一些重复计算的过程,减少程 ...

  2. OpenCV算法加速(4)官方源码v4.5.5的默认并行和优化加速的编译选项是什么?请重点关注函数cv::getBuildInformation()的返回值

    举例opencv v4.5.5版本源码,Windows x64,VS2019,CMake https://github.com/opencv/opencv/tree/4.5.5 https://sou ...

  3. OpenCV算法加速(2)使用SIMD指令集(MMX、SSE、AVX)和MIPP实现视觉算法优化

    一.概述 很多人觉得OpenCV速度比较慢,其实提升OpenCV运行速度,最常见的就是重新编译OpenCV,添加各种指令集优化支持. SIMD(Single Instruction Multiple ...

  4. 学习算法你必须知道的一些基础知识(文末福利)

    点击标题下「异步社区」可快速关注 机器学习是解决很多文本任务的基本工具,本文自然会花不少篇幅来介绍机器学习.要想搞明白什么是机器学习,一定要知道一些概率论和信息论的基本知识,本文就简单回顾一下这些知识 ...

  5. 广告算法所需要搞懂的基础知识

    先简单解释下基本的:DSP(Demand Side Platform)是需求方平台,负责接受投放需求,找人群数据,实现投放竞价等功能的那么一个中央管理控制平台.DMP(Data Management ...

  6. 关于实现Halcon算法加速的基础知识(多核并行/GPU)

    一.提高Halcon的运算速度,有以下几种方法: 1.Multithreading(多线程) 2.Automatic Parallelization(自动操作并行化) 3.Compute device ...

  7. python基础知识及数据分析工具安装及简单使用(Numpy/Scipy/Matplotlib/Pandas/StatsModels/Scikit-Learn/Keras/Gensim))

    Python介绍. Unix & Linux & Window & Mac 平台安装更新 Python3 及VSCode下Python环境配置配置 python基础知识及数据分 ...

  8. OpenCv算法的基本介绍与应用

    OpenCv算法的基本介绍与应用 一.目录 二.图像处理流程 三.图像预处理 3.1噪声分类 3.1.1随机噪声 3.1.2椒盐噪声 3.1.3 高斯噪声 3.2 滤波 3.2.1 均值滤波 3.2. ...

  9. 热对流方程加速的OpenMP实现

    1. 热对流问题的Matlab实现 热对流问题不是本文的重点,对这个问题不了解的话可以参考别的学习资料.OpenMP的基础知识可以参考网上很多资料,也可以参考本博主另外的一片博客<OpenMP基 ...

最新文章

  1. 动态规划—最长公共子序列问题 HDU-1159 Common Subsequence
  2. 【转】Android 快捷方式的创建
  3. 玩游戏计算机配置,玩游戏的电脑需要什么配置?
  4. 【机器学习入门笔记1:anaconda一站式开发环境搭建】20190122
  5. webstorm怎么跑项目_快讯!明年厦门中考体育项目定了!初三家长抽的!其他地市抽到啥?...
  6. Visual SVN Server 远程管理
  7. kibana操作elasticsearch:多字段查询(multi_match)
  8. 【实战篇】| 小鹿教你用动态规划撩妹的正确方式
  9. OpenLayers 官网例子的中文详解
  10. 信元模式mpls 避免环路_【基础】交换机堆叠模式
  11. 服务器存档修改,云服务器存档修改器
  12. 并发数据结构-1.1 并发的数据结构的设计
  13. 基于javaSwing+文本存储的学生信息管理系统设计实现
  14. codeblocks 编译java_在CodeBlocks中发布编译程序
  15. PHP设计模式——单例模式
  16. SQL Server 中死锁产生的原因及解决办法
  17. Windows10永久关闭自动更新,禁止windows10自动更新方法!
  18. 哈尔滨工业大学计算机考研难吗,哈尔滨工业大学计算机考研经验:只有意志坚强才能到达彼岸...
  19. bzoj3144 切糕
  20. 【转载】C语言嵌入式系统编程修炼之二:软件架构篇

热门文章

  1. 一个牛人给我们的建议
  2. 2023牛客寒假算法基础集训营2 -- E-Tokitsukaze and Function(数学 二分)
  3. android runtime异常,E / AndroidRuntime:致命错误:主要
  4. R7 5700U和R7 4800U 参数对比差距大吗
  5. 计算机达人成长之路(4)连载
  6. Linux mmap讲解
  7. Web Apps来袭,html5解放开发者
  8. transformer
  9. 想象力比知识更重要么?提出问题比解决问题更重要?
  10. 狂神说Mybatis3 29道习题