opencv ncnn warpaffine 性能测试

2021-03-07 星期日

opencv ncnn warpaffine 性能测试

允许在不修改内容前提下转载本文

0x0 先写结论

  • 本文测试针对手机平台ARM CPU
  • 如果要用 opencv,强烈建议使用 3.4.13/4.5.1,有SIMD优化,性能较opencv2明显提升
  • ncnn 在小图旋转上优势明显,在大图旋转上速度不如 opencv3/4
  • 图片缩小时,ncnn 显著加速
  • 举个例子,人脸 5 点 warpaffine 到 112x112 送给模型做识别,尺寸较小,ncnn 速度更快
  • 总之,ncnn 的 warpaffine 实现还是不错的,推荐
  • 以及,要用 opencv 的话,推荐使用包体积更小的 opencv-mobile
https://github.com/Tencent/ncnngithub.com
nihui/opencv-mobilegithub.com图标

0x1 起源

应着里群开发者需求,这周六下午我在 bilibili 直播写代码,优化 ncnn warpaffine 函数

噫,你居然还不知道 ncnn 已经有 warpaffine 接口了吗?

用法挺简单的,下面两个函数效果等价,稍微看下就明白了吧~

static void opencv_rotate(const cv::Mat& src, cv::Mat& dst, const cv::Mat& tm)
{
    cv::warpAffine(src, dst, tm, src.size(), cv::INTER_LINEAR | cv::WARP_INVERSE_MAP);
}

static void ncnn_rotate(const cv::Mat& src, cv::Mat& dst, const float* tm)
{
    const int w = src.cols;
    const int h = src.rows;
    const int c = src.channels();

    dst.create(h, w, src.type());

    if (c == 1) ncnn::warpaffine_bilinear_c1(src.data, w, h, dst.data, w, h, tm);
    if (c == 2) ncnn::warpaffine_bilinear_c2(src.data, w, h, dst.data, w, h, tm);
    if (c == 3) ncnn::warpaffine_bilinear_c3(src.data, w, h, dst.data, w, h, tm);
    if (c == 4) ncnn::warpaffine_bilinear_c4(src.data, w, h, dst.data, w, h, tm);
}

0x2 测试方法

  • 预定义了9种旋转角度和缩放系数的组合,图片沿中心点旋转缩放(inverse)
  • 图片尺寸选择 320x240/640x480/1280x720 三种
  • opencv 采用体积小巧的 opencv-mobile 预编译库,分别有 2.4.13.7/3.4.13/4.5.1 三个版本
  • ncnn 是直播优化后提交的代码,也就是 git 的最新版本
  • 测试设备CPU是 qcom425 单线程,每个测试循环跑100次取最低耗时值
  • 因为全部展示太多,挑选了比较常见的单通道和3通道的结果
https://github.com/nihui/opencv-mobilegithub.com

0x3 为啥大图上 ncnn 速度赢不过 opencv3/4 ?

首先,主要计算量在线性插值

out = (a0 * alpha0 + a1 * alpha1) * beta0 + (b0 * alpha0 + b1 * alpha1) * beta1

opencv 会把这个公式转化为

a0b0 = alpha0 * beta0
a1b0 = alpha1 * beta0
a0b1 = alpha0 * beta1
a1b1 = alpha1 * beta1

out = a0 * a0b0 + a1 * a1b0 + b0 * a0b1 + b1 * a1b1

其中,a0b0/a1b0/a0b1/a1b1 预先计算好放在全局数组中,插值时拿出来,下标采用 5bit x 5bit 量化后的索引,共 32x32 个系数数据

可见,opencv 的插值只有 4 次乘法,ncnn 按照原公式需要 6 次乘法,乘法次数显著降低,在大图上差距体现非常明显

——— 那么,为啥 ncnn 不把这个技术也用上呢?

——— 因为我感觉现在已经够用了,比如人脸图片的裁剪什么的;加查表会把代码弄复杂,增加白嫖门槛;而且大图旋转用啥 CPU,用 GPU 不好嘛...

原文地址:点击此处查看原文