处理器:E3 1230,基于opencv3.0官方源码编译版本(自带IPP加速)
输入数据 1000*1000 矩阵
测试方法:连续运行10000次,取平均值
规律:尽量使用浮点数据进行处理,因为函数处理前会先转为浮点类型,该操错也耗时
1、寻找大值最小值
minMaxLoc
对于CV_32F类型,0.25ms,输入整型数据会大大增加耗时
耗时基本可以忽略
2、积分图
integral
对于CV_32F类型,6ms,若为整型数据耗时稍低
3、高斯滤波
GaussianBlur
对于CV_32F类型,1.4ms
对于CV_16U类型,7.5ms
对于CV_8U类型,1.3ms
耗时明显受矩阵大小的影响
4、矩阵翻转函数
flip对于CV_16U, 0.12ms,对于浮点会慢一些
耗时基本可以忽略
5、图像旋转
getRotationMatrix2D warpAffinegetRotationMatrix2D基本不耗时
warpAffine对于CV_16U,2.6ms,对于浮点,1.9ms
7、图像(矩阵)数据类型转换
convertToCV_32F转CV_16U, 0.2ms
CV_16U转CV_32F, 0.2ms
速度不算很慢,但前提是转换前和转换后的矩阵已经创建好(一个CV_32F的Mat和一个CV_16U的Mat,大小均为1000*1000)
通过循环和指针遍历每一个像素并强制类型转换的耗时:
CV_32F转CV_16U, 0.5ms
CV_16U转CV_32F, 0.4ms
可见,convertTo方法是经过优化的(IPP),即使实际中是一个数组(动态数组)也可以通过convertTo方法间接提高速度
8、数据块拷贝
memcpyushort,0.1ms
float,0.3ms
耗时基本可以忽略
9、矩阵运算
数据类型为float
如,矩阵减法
subtract0.3~0.5ms
通过循环和指针遍历每一个像素并作减法的耗时:0.3ms
可见,使用库函数反而慢了
还有一点值得注意:遍历矩阵的循环内部,尽量不要加入分支结构(if、switch)这样会大大增加耗时
如,矩阵乘法
multiply,对于in-place操作,1.2ms
而遍历,0.18ms
注意,相乘尽量采用
a *= factor的形式,比
a = a * factor要快
还有一种方式是矩阵乘上一个常数,如
Mat a; a *= 10;虽然速度优于使用multiply函数,但如果常数是浮点数,会比整数慢,且没有遍历的方式快
结论:如果算法实时性要求高(达到ms级),则尽量采用遍历方式进行矩阵运算