在Android之类的移动环境中,如果选择OpenCV进行生产,您的重要目标之一就是减小库的大小并使其性能就绪。
OpenCV是一个库,其中包含大量的Computer Vision算法,但是通常,在应用程序中使用这些算法的一小部分。因此,将需要的内容包括在内,而将其余的内容排除在外是非常有意义的。
静态库与动态库
一个库可以静态随您的应用程序代码进行编译。
另外,它可以在运行时动态链接。
在本教程中,我们将创建一个动态库(即共享对象(.so))。
环境:
Ubuntu16.4 (docker container)
cmake3.7.2
NDKr14b
OpenCV3.4.1 (or 3.0.x,2.4需要低版本cmake)
Targetarmeabi-v7a (ARM based)
Android API23
1.下载 sdk
https://dl.google.com/android/repository/android-ndk-r14b-linux-x86_64.zip
2.解压 sdk到/opt/android-ndk-r14b
3.创建新的 toolchain 编译工具链(交叉编译)
root@dc:/opt/android-ndk-r14b# ./build/tools/make_standalone_toolchain.py \ --arch arm \ --api 23 \ --install-dir /tmp/my-android-toolchain
4.导出工具链编译工具链
$ exportANDROID_STANDALONE_TOOLCHAIN=/tmp/my-android-toolchain/
5.安装ninja,ant
apt-get install ninja-build ant
6.下载&编译opencv
$ cd opencv/
$ mkdir build $ cd build $ cmake \
-DCMAKE_TOOLCHAIN_FILE=../platforms/android/android.toolchain.cmake \
-DANDROID_STL=gnustl_shared \
-DANDROID_NATIVE_API_LEVEL=23 ..
make -j12
6.优化,减少非必要的 cv模块
cv中的全部模块有:
libopencv_calib3d.a libopencv_flann.a libopencv_java3.so libopencv_shape.a libopencv_video.a libopencv_core.a libopencv_highgui.a libopencv_ml.a libopencv_stitching.a libopencv_videoio.a libopencv_dnn.a libopencv_imgcodecs.a libopencv_objdetect.a libopencv_superres.a libopencv_videostab.a libopencv_features2d.a libopencv_imgproc.a libopencv_photo.a libopencv_ts.a
常用模块有:
libopencv_core.alibopencv_imgproc.aimgcodecs
通过选择必要.a 文件,进行手动控制.so 体积,这里以core,imgpro两个模块演示.
/home/linuxbrew/toolchain_opencv_android/bin/arm-linux-androideabi-gcc-4.9 -shared -o libopencv_tiny.so --sysroot=/home/linuxbrew/toolchain_opencv_android/sysroot -Wl,--whole-archive libopencv_core.a libopencv_imgproc.a -Wl,--no-whole-archive
这里需要选择使用gcc,或者g++,wl选项可能不低版本中不支持.
体积从7.8->3.7
7.优化,strip 动态库
/home/linuxbrew/toolchain_opencv_android/bin/arm-linux-androideabi-strip --strip-unneeded libopencv_tiny.so
体积从7.8->2.9
8.优化,手动控制.o文件
bin/arm-linux-androideabi-ar x libopencv_core.a
我们可以简单的理解为一个 cpp 文件编译成.o 文件,多个.o 可以合并为一个.a,多个.a或者.o文件连接成.so,这里是把.a 解压,选取需要的.a 文件,然后再组装我们需要的.so
9.优化,手动控制.cpp文件文件
如在imgpro,即图像处理模块中,在端上处理时,更可能的情况是什么了变换等方法,如果透视,仿射,缩放,插值,颜色变换,但是图像结构分析和形态的contour ,hull基本不会在端上使用,效率也比较低。此时可以考虑修改c++文件,或者使用8中的方法去掉相应的.o 文件。
10.NDK,是一个总结的非常好的包,里面有各种平台的所需要的构建工具,包括x86,arm64等。在新的环境下,可以直接下载并配置好,不需要另外 apt 安装其他三方库。
结论
可以通过,6,7,正常减少体积,也可以8,7更精细减少体积,或者9,7,更精细减少。
同时建议,不使用.so 进行进行发布,而采用.a方式与业务合并编译,这样可以有效减少非必要函数的自动打包发布。
网友评论