TBB、OpenCV混合编程

TBB提供了Parallel_for、Parallel_do、Parallel_reduce等通用并行算法,可以应用在不同的并行算法场合,Parallel_for适合用在多个数据或请求之间彼此没有依赖关系,所要进行的操作也是一样的情况。


Parallel_for的调用格式:

Parallel_for(first,last,step,func)

表示一个循环的并行执行,等价于以下操作:

for(auto i =first;i<last; i+=step)func(i);


第三个参数step可以省略,默认为1。Parallel_for的使用:

#include <tbb/tbb.h>
#include <iostream>

using namespace std;
using namespace tbb;

void func1(int a)
{
	cout << a << endl;
}

int main()
{
	parallel_for(0, 10, 2, func1); //step为2
	//parallel_for(0, 10, func1); //默认的step为1
	getchar();
	return 0;
}

其中一次输出为0 4 2 6 8。


在OpenCV中有些场景需要读入多张图片,并对这些图片进行预处理,如二值化、滤波等这种场景可以使用TBB进行加速。以下是使用parallel_for模板读入多幅图片并执行高斯滤波的示例:

#include <tbb/tbb.h>
#include <iostream>
#include <core/core.hpp>
#include <imgproc.hpp>
#include <highgui/highgui.hpp>

using namespace std;
using namespace tbb;
using namespace cv;

vector<Mat> imageVec;
spin_mutex mutexObj; //互斥锁

void ReadImage(int a)
{
	//获取图像名字,在硬盘上按0~9.jpg排列
	stringstream stringstr;
	stringstr << a;
	string imagePath;
	stringstr >> imagePath;
	imagePath += ".jpg";
	Mat image = imread(imagePath);

	mutexObj.lock(); //互斥
	imageVec.push_back(image);
	mutexObj.unlock(); //解除互斥
}

void GaussOperate(int a)
{
	GaussianBlur(imageVec[a], imageVec[a], Size(11, 11), 10);
}

int main()
{
	parallel_for(0, 10, 1, ReadImage); //多线程读入图片
	parallel_for(0, 10, 1, GaussOperate);  //分别执行高斯滤波操作	
	imshow("高斯滤波", imageVec[0]); //显示其中一幅图像
	waitKey();
	return 0;
}


其中一幅原始输入图像:



滤波效果:



程序中首先定义了一个spin_mutex类的对象mutexObj。TBB中spin_mutex类用来对多线程中一段代码或变量提供同步和互斥保护,保证在同一时间只有一个线程对这段代码或变量进行操作。


lock函数开启互斥锁,unlock函数解除互斥。TBB中提供的互斥锁除了spin_mutex外还有5个: mutex、quening_mutex、spin_rw_mutex、recurisve_mutex、queuing_rw_mutex。


上例中高斯滤波部分只有一个滤波操作,使用lambda表达式更为简洁,上例中的main函数可以改写为:

int main()
{
	parallel_for(0, 10, 1, ReadImage); //多线程读入图片
	parallel_for(0, 10, 1, [](int a) {GaussianBlur(imageVec[a],imageVec[a], Size(11, 11), 10); }); //lambda表达式写法	
	imshow("高斯滤波", imageVec[0]);
	waitKey();
	return 0;
}


parallel_for(0, 10, 1, GaussOperate)等价于parallel_for(0, 10, 1, [](int a) {GaussianBlur(imageVec[a],imageVec[a], Size(11, 11), 10); })


原文地址:https://www.cnblogs.com/mtcnn/p/9411878.html