opencv 并行计算函数 parallel_for_的使用

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中,以下并行框架按照以下顺序提供: 
1. 英特尔线程构建块(第三方库,应显式启用),如TBB 
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中的选项并重建库。第二个(弱)前提条件与要实现的任务更相关,因为并不是所有的计算都是合适的/可以被平行地运行。为了保持简单,可以分解成多个基本操作而没有内存依赖性(无可能的竞争条件)的任务很容易并行化。计算机视觉处理通常易于并行化,因为大多数时间一个像素的处理不依赖于其他像素的状态。

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
转:https://blog.csdn.net/qq_31806429/article/details/79242399

猜你喜欢

转载自blog.csdn.net/eric_e/article/details/83904867