OpenCV在移动端的优化

先说一下OpenCV在Android移动端的历史。OpenCV官方正式开始支持Android平台的是在OpenCV 2.4版本,2012年。OpenCV4Android是OpenCV库支持Android接口的官方命名。共提供两种接入方式:使用OpenCV Java API以及使用Android NDK。
使用Java API的好处是接入简单,缺点是只支持OpenCV的部分库函数以及由于是封装了C++而带来的一小部分性能损失。具体可以看一下下面两张图:假如视频的每一帧都需要调用三个OpenCV的函数,使用Java API的话就需要有三对JNI的输入输出,也就是应用每一帧会导致6次JNI的调用;而使用native C++的方式时,OpenCV的部分完全由C++写,在调用OpenCV的函数时完全绕开了JNI的调用,就会将每一帧JNI的调用次数从6次减到了2次,对性能表现会有优化。当然,如果只是调用一次OpenCV函数的过程的话,性能优化方面其实是不明显的。

OpenCV在移动端的优化_第1张图片
bdti figure 2 500.jpg

使用Java API

OpenCV在移动端的优化_第2张图片
bdti figure 3 500.jpg

使用Native C++
OpenCV针对NVDIA的的Tegra3及以上平台系列做了针对Android操作系统的优化(TADP, Tegra Android Development Pack),在Tegra上使用OpenCV通常能达到几倍快于一般平台上基于Android的实现。也是从Tegra3开始,OpenCV开始支持 ARM的SIMD扩展,NEON。这里在Google Play上有专门一个针对Tegra平台性能的Demo—OpenCV for Tegra Demo。以上可以为今后针对Tegra的芯片优化做参考。
NEON专为矢量操作设计,适合用于图片处理,对许多视觉算法可以显著提升速度。下面举个栗子:将RGB转为灰图,一般的颜色转换这么写,每次处理一个像素:

{
    for(int i=0; i>8;
    }
}```
使用NEON intrinsics
```void rgb_to_gray_neon(const uint8_t* rgb, uint8_t* gray, int num_pixels)
{
    // We'll use 64-bit NEON registers to process 8 pixels in parallel.
    num_pixels /= 8;
    // Duplicate the weight 8 times.
    uint8x8_t w_r = vdup_n_u8(77);
    uint8x8_t w_g = vdup_n_u8(150);
    uint8x8_t w_b = vdup_n_u8(29);
    // For intermediate results. 16-bit/pixel to avoid overflow.
    uint16x8_t temp;
    // For the converted grayscale values.
    uint8x8_t result;
    for(int i=0; i

你可能感兴趣的:(OpenCV在移动端的优化)