【竹篮打水】OpenCV4.x 中新增并行代码执行演示

简介: 【竹篮打水】OpenCV4.x 中新增并行代码执行演示

OpenCV支持的并行框架

OpenCV从4.5版本开始,新增了并行代码执行支持,以常见的图像像素遍历卷积计算为例,演示OpenCV中卷积计算并行代码执行与非并行的卷积计算代码执行,同时对比时间消耗。OpenCV并行框架支持下面几种方法启用并行加速,分别是:

1. Intel TBB (第三方库,需显式启用)
2. C=并行C/C++编程语言扩展 (第三方库,需显式启用)
3. OpenMP (编译器集成, 需显式启用)
4. APPLE GCD (苹果系统自动使用)
5. Windows RT并发(Windows RT自动使用)
6. Windows并发(运行时部分, Windows,MSVC++ >= 10自动使用)
7. Pthreads

在VS IDE中开启OpenMP,只需要右键点击项目,从属性中

这样就可以开启并行加速。

卷积并行实现与时间比较

OpenCV支持两种方式的并行代码实现,分别是:

parallel_for_
ParallelLoopBody

以3x3卷积为例,原始的代码实现如下:

start = (double)cv::getTickCount();
for (int row = 0; row < rows; row++) {
  for (int col = 1; col < cols - 1; col++)
  {
    int sum = src.at<uchar>(row, col) + src.at<uchar>(row - 1, col) + src.at<uchar>(row + 1, col) +
      src.at<uchar>(row, col - 1) + src.at<uchar>(row - 1, col - 1) + src.at<uchar>(row + 1, col - 1) +
      src.at<uchar>(row, col + 1) + src.at<uchar>(row - 1, col + 1) + src.at<uchar>(row + 1, col + 1);
    int pv = sum / 9;
    dst.at<uchar>(row, col) = pv;
  }
}

parallel_for_ 3x3卷积的代码实现如下

double start = (double)cv::getTickCount();
parallel_for_(Range(0, rows * cols), [&](const Range &range)
{
  for (int r = range.start; r < range.end; r++)
  {
    int i = r / cols, j = r % cols;
    double value = 0;
    for (int k = -sz; k <= sz; k++)
    {
      uchar *sptr = src.ptr(i + sz + k);
      for (int l = -sz; l <= sz; l++)
      {
        value += kernel.ptr<double>(k + sz)[l + sz] * sptr[j + sz + l];
      }
    }
    dst.ptr(i)[j] = saturate_cast<uchar>(value);
  }
});
double time = (((double)cv::getTickCount() - start)) / cv::getTickFrequency();
std::cout << "parallel_for_conv3x3 execute time: " << time * 1000 << " ms" << std::endl;

ParallelLoopBody 3x3卷积的代码实现如下

class parallelConvolution : public ParallelLoopBody
{
private:
  Mat m_src, &m_dst;
  Mat m_kernel;
  int sz;
public:
  parallelConvolution(Mat src, Mat &dst, Mat kernel)
  : m_src(src), m_dst(dst), m_kernel(kernel)
  {
    sz = kernel.rows / 2;
  }
  virtual void operator()(const Range &range) const CV_OVERRIDE
  {
    for (int r = range.start; r < range.end; r++)
    {
      int i = r / m_src.cols, j = r % m_src.cols;
      double value = 0;
      for (int k = -sz; k <= sz; k++)
      {
        const uchar *sptr = m_src.ptr(i + sz + k);
        for (int l = -sz; l <= sz; l++)
        {
          value += m_kernel.ptr<double>(k + sz)[l + sz] * sptr[j + sz + l];
        }
      }
      m_dst.ptr(i)[j] = saturate_cast<uchar>(value);
    }
  }
};

调用方式如下:

start = (double)cv::getTickCount();
parallelConvolution obj(src, dst, kernel);
parallel_for_(Range(0, rows * cols), obj);
time = (((double)cv::getTickCount() - start)) / cv::getTickFrequency();
  std::cout << "parallelConvolution conv3x3 execute time: " << time * 1000 << " ms" << std::endl;

运行结果如下:

我晕倒,不是说并行加速了吗,可是我得不到OpenCV官方教程上那样的明显加速的结果,因为教程上没有说明它到底是用了那个并行加速框架得到的。有时候 “尽信书不如无书”

对此,我自己也有一些原因分析,但是更希望大家留言分析一下相关原因,为什么没有加速效果??

相关文章
|
计算机视觉 Python
最快速度写出一个识别效果——OpenCV模板匹配(含代码)
最快速度写出一个识别效果——OpenCV模板匹配(含代码)
490 0
|
7月前
|
传感器 C++ 计算机视觉
【opencv3】详述PnP测距完整流程(附C++代码)
【opencv3】详述PnP测距完整流程(附C++代码)
|
7月前
|
机器学习/深度学习 算法 数据可视化
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)-2
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)
|
6月前
|
算法 开发工具 计算机视觉
【零代码研发】OpenCV实验大师工作流引擎C++ SDK演示
【零代码研发】OpenCV实验大师工作流引擎C++ SDK演示
94 1
|
4月前
|
算法 计算机视觉 Python
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
该文章详细介绍了使用Python和OpenCV进行相机标定以获取畸变参数,并提供了修正图像畸变的全部代码,包括生成棋盘图、拍摄标定图像、标定过程和畸变矫正等步骤。
python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)
|
7月前
|
机器学习/深度学习 Ubuntu Linux
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)-1
计算机视觉+深度学习+机器学习+opencv+目标检测跟踪+一站式学习(代码+视频+PPT)
|
4月前
|
计算机视觉 Python
opencv在pycharm不能自动补全代码
opencv在pycharm不能自动补全代码
31 0
|
6月前
|
监控 安全 计算机视觉
实战 | 18行代码轻松实现人脸实时检测【附完整代码与源码详解】Opencv、人脸检测
实战 | 18行代码轻松实现人脸实时检测【附完整代码与源码详解】Opencv、人脸检测
|
7月前
|
算法 API 计算机视觉
基于opencv的大米计数统计(详细处理流程+代码)
基于opencv的大米计数统计(详细处理流程+代码)
基于opencv的大米计数统计(详细处理流程+代码)
|
7月前
|
计算机视觉 索引 Python
分析”圣诞帽“代码,入门OpenCV
分析”圣诞帽“代码,入门OpenCV
分析”圣诞帽“代码,入门OpenCV