OpenCV中的filter2D函数如何比我自己的卷积代码执行效率更高?

问题描述 投票:0回答:1

我正在尝试用 C++ 编写自己的代码来实现卷积。 并且内核是 11 x 11 并且不可分离。所以我的代码是这样的:

for(int i = 0; i < image.rows; ++i){
    for(int j = 0; j < image.cols; ++j){
       int tmp, sum; 
       for(int m= 0; m < kernel.rows; ++m){
          for(int n = 0; n < kernel.cols; ++n){
             tmp = image[i+m-(Size_kernel-1)/2][j+n-(Size_kernel-1)/2];
             float kernel_index = kernel[m][n];
             float index_mult = (float)index_mult * kernel_index;
             sum = sum + index_mult;
          }
       }
      new_image[i][j] = sum; 
    }
 }

我们可以看到这段代码的复杂度很大。而且当我运行程序时,速度非常慢。

但是,当我将两个矩阵插入 OpenCV 中的“filter2D”函数时。只需很短的时间即可显示结果。谁能解释一下OpenCV中的filter2D是如何实现卷积的?为什么OpenCV和我自己的代码效率相差很大?谢谢!

c++ opencv image-processing filtering
1个回答
0
投票

快速卷积码基于 3 个属性:

  1. 缓存位置
    处理后的数据可在 CPU 缓存中使用。
    这是使用图块中的工作完成的。
  2. SIMD 代码
    现代 CPU 具有矢量运算单元(例如
    x64
    中的 AVX 和
    ARM
    中的 SVE)。所以代码应该能够在 SIMD 线路上运行。
    有时它是通过手动代码完成的。有时通过以允许编译器生成此类代码的方式编写代码。
  3. 并行化
    如果数据的局部性不会创建带宽受限的代码,那么并行化将能够获得收益。

关于利用基于 DFT 的卷积。对于单个卷积的小内核,开销太大,基于空间的卷积会表现更好。

© www.soinside.com 2019 - 2024. All rights reserved.