#opencv 并行计算函数 parallel_for_
前面的话
在使用opencv的过程中,对图片的处理计算量还是很大的,所以在实施运行的程序中如何高效的计算会节省很多时间。现有的方法有很多,如OpenMp,TBB,OpenCL,当然还有Nvidia的CUDA。
但是OpenMP在windows的VS上支持的很好,设置简单,效果也还不错,但是在Linux虽然也支持,
但是我用Cmake时,感觉效果并不明显。TBB和OpenCL没有直接用过。CUDA是个好东西,但是并
不太适合毫秒级别的程序运行,单一张图片在cpu和gpu之间的传输时间就已经达到300ms(我用
的是opencv的cuda库函数);在TX2上直接对cuda进行编程,数据的传输也是在50ms(不包含初始化)以上,根本不能拿来做实时的运算。所以如何在cpu上更加高效的计算变得尤为重要。偶然间发现了opencv的并行计算函数parallel_for_,它整合了上述的多个组件
在OpenCV 3.2中,以下并行框架按照以下顺序提供:
- 英特尔线程构建块(第三方库,应显式启用),如TBB
- C =并行C / C ++编程语言扩展(第三方库,应明确启用)
- OpenMP(集成到编译器,应该被显式启用)
- APPLE GCD(系统范围广,自动使用(仅限APPLE))
- Windows RT并发(系统范围,自动使用(仅Windows RT))
- Windows并发(运行时的一部分,自动使用(仅限Windows) - MSVC ++> = 10))
- Pthreads(如果有的话)
您可以看到,OpenCV库中可以使用多个并行框架。一些并行库是第三方库,必须在CMake(例如TBB,C =)中进行显式构建和启用,其他可以自动与平台(例如APPLE GCD)一起使用,但是您应该可以使用这些库来访问并行框架直接或通过启用CMake中的选项并重建库。第二个(弱)前提条件与要实现的任务更相关,因为并不是所有的计算都是合适的/可以被平行地运行。为了保持简单,可以分解成多个基本操作而没有内存依赖性(无可能的竞争条件)的任务很容易并行化。计算机视觉处理通常易于并行化,因为大多数时间一个像素的处理不依赖于其他像素的状态。
OpenCV在编译时需要使能OpenMV,TBB等
代码简单的贴出来,这里记录一下:在c++11中,可以不必定一个类去继承并行计算循环体类(ParallelLoopBody),可以直接使用,如main中所示在c++11之下的就需要继承一下该并行计算循环体了,继承的原因个人认为是通过复写虚函数,实现并行计算
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
using namespace std;
using namespace cv;
class Parallel_My : public ParallelLoopBody
{
public:
Parallel_My (Mat &img, const float x1, const float y1, const float scaleX, const float scaleY)
: m_img(img), m_x1(x1), m_y1(y1), m_scaleX(scaleX), m_scaleY(scaleY)
{
}
virtual void operator ()(const Range& range) const
{
for (int r = range.start; r < range.end; r++) //process of for loop
{
/***
***/
}
}
Parallel_My& operator=(const Parallel_My &) {
return *this;
};
private:
Mat &m_img;
float m_x1;
float m_y1;
float m_scaleX;
float m_scaleY;
};
int main()
{
//! [mandelbrot-transformation]
Mat Img(4800, 5400, CV_8U);
float x1 = -2.1f, x2 = 0.6f;
float y1 = -1.2f, y2 = 1.2f;
float scaleX = mandelbrotImg.cols / (x2 - x1);
float scaleY = mandelbrotImg.rows / (y2 - y1);
#ifdef CV_CXX11 //method one
parallel_for_(Range(0, Img.rows*tImg.cols), [&](const Range& range)
{
for (int r = range.start; r < range.end; r++) //这是需要并行计算的for循环
{
}
});
#else //method two
Parallel_My parallel_my0(Img, x1, y1, scaleX, scaleY);
parallel_for_(Range(0, Img.rows*Img.cols), parallel_my0);
#endif
}
可以参考这里:
1.使用parallel_for_优化代码
2. 官网document
亲,播客有帮助的话,请扫一扫二维码赏点奖励金吧~