OpenCV: filter2D函数的计算效率
OpenCV: Computational efficiency of filter2D function
如果我想在OpenCV中使用内核对图像进行卷积,我可以使用filter2D
函数。另一种选择是像这篇文章中那样使用for循环创建我自己的过滤器。
filter2D会比文章中的代码更快吗?如果是,是什么让它更快?
我试着看filter2d的代码,但无法理解。我是openCV的新手,在这方面的任何帮助都是非常感谢的。
事实上,大多数OpenCV都比朴素的方法快得多!对于卷积,它们通常使用以下两种基本优化之一:
-
分离卷积。对某些类型的内核利用了"卷积的关联属性"。对于
M-by-N
图像和P-by-Q
核,天真的方法是M*N*P*Q
。如果内核是可分离的,你可以在M*N(P+Q)
中完成。这是巨大的!你会注意到OpenCV的filter2d源代码在可能的情况下利用了这一点。 -
卷积定理。这种优化甚至更好,但它有点复杂。基本上:空间域中的卷积相当于频域中的逐点乘法。这意味着如果你把你的图像和内核通过FFT,你的卷积可以从二次(朴素)时间复杂度到O(n log n)!查看Wikipedia上的卷积定理
Filter2d是有效的,当你的过滤器大小是小的,并且比你提到的帖子更快。但是,当内核变大时,运行时会急剧增加。
事实上,有许多实现比OpenCV快得多,包括那些基于递归和积分图像的实现。
递归实现的关键思想是二维卷积可以分离成几个一维卷积,一维卷积可以写成递归。谷歌一下递归高斯滤波器或者递归卷积就知道了。
同样,你可以分解你的核并使用几个积分图像实现卷积。谷歌一下核积分图像或者余弦积分图像。
无论哪种方式,运行时都不会随着内核大小的增加而增加。因此,当你的内核很大时,这些实现比OpenCV的filter2d要高效得多。
理解递归实现或积分图像实现需要一些信号处理的数学背景。如果实现的效率是你最关心的,你最好学习它们并自己编写一个过滤器。如果没有,就使用opencv的filter2d,记住要避免大内核。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 如何计算文件中的"columns"数?
- 计算排序向量的向量中唯一值的计数
- 如何使用 std::累积在 C++ 中计算总和立方体
- 使用Qt C++计算类似Git的SHA1哈希
- OpenCV C++.快速计算混淆矩阵
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- C++如何计算用户输入的数字中的偶数位数
- 寻求提高Microsoft密封库计算效率的方法
- C 矩阵计算效率
- 在opencv中,使用垫子类型计算马氏距离太慢了。如何提高效率?
- 多线程计算均值和std并不能提高效率
- 提高了一个非常简单但用途广泛的函数(计算晶格中原子的邻居)的效率
- 计算效率高的C++-一般阅读
- 在c++中将两个相关的std::堆栈合并为std::map的计算效率如何?
- OpenCV: filter2D函数的计算效率