Android OpenCV DNN Objects Detection

这标题都是英文,看了一下专业词汇多还真不好写中文。本文的内容是介绍 OpenCV DNN(Deep Neural Networks)模块在 Android 上的使用,运行深度学习模型来做图像的多目标识别。移动设备上基于深度学习的图像识别技术离实际应用还有段距离,不过该技术却有着惊艳的效果。

计算机视觉开源软件库 OpenCV 刚升级到了 3.4.1,Android Studio 现在也是 3.0.1 的版本。虽然软件库和开发工具都做了版本更新,还是可以参考这篇博文“将 OpenCV 打包为 Android AAR”创建 AAR 模块。新版本除了集成了一些补丁和问题修复外,JNI 库也整理得更好了,此外还发现新增了一个使用 Android Camera2 接口的 CameraView (org.opencv.android.JavaCamera2View.java)。但是我在手机上用这个 View 发现画面的色彩不对,想尝鲜的朋友可以调试一下。启用 Camera2 接口应该可以在 Android 上更好的适配硬件加速,将视觉处理大量的浮点计算交给 GPU 去做。

将之前创建的 OpenCV AAR 模块升级到 3.4.1,App 依赖此模块。在 Android 手机上(Snapdragon 835 CPU)运行可以看到以下 logcat 信息,接下来可以参考 OpenCV DNN Toturial 在 App 上使用 DNN。

General configuration for OpenCV 3.4.1 =====================================
Version control: 3.4.1
Platform:
Timestamp: 2018-02-23T12:15:01Z
Host: Linux 4.13.0-32-generic x86_64
Target: Linux 1 aarch64
CMake: 2.8.12.2
CMake generator: Ninja
CMake build tool: /usr/bin/ninja
Configuration: Release
CPU/HW features:
Baseline: NEON
requested: NEON FP16
required: NEON
disabled: VFPV3
C/C++:
... 此处内容太多已省略
OpenCV modules:
To be built: calib3d core dnn features2d flann highgui imgcodecs imgproc java java_bindings_generator ml objdetect photo python_bindings_generator shape stitching superres video videoio videostab
Disabled: js world
Disabled by dependency: -
Unavailable: cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev python2 python3 ts viz
Applications: android_examples
Documentation: NO
Non-free algorithms: NO
Android:
Android ABI: arm64-v8a
STL type: gnustl_static
Native API level: android-21
SDK target: android-21
Android NDK: /opt/android/android-ndk-r10e (toolchain: aarch64-linux-android-4.9)
android tool: /opt/android/android-sdk-java7/tools/android (Android SDK Tools, revision 25.2.2.)
... 后面已省略

OpenCV DNN 模块可以读取多种深度学习框架的网络模型,生成 DNN 的网络对象(DNN 不支持模型训练)。模型文件放到 assets 打包进 APK,运行时复制(一次)到 App 目录后 DNN 就可以读取。Java API 的注释少,这里是打开 C++ API 来看看读取 Caffe 模型的说明。

读取模型

/** @brief Reads a network model stored in <a href="http://caffe.berkeleyvision.org">Caffe</a> framework's format.
* @param prototxt path to the .prototxt file with text description of the network architecture.
* @param caffeModel path to the .caffemodel file with learned network.
* @returns Net object.
*/
CV_EXPORTS_W Net readNetFromCaffe(const String &prototxt, const String &caffeModel = String());

在摄像头图像帧里运行模型计算输出,标注识别结果。可以参考官方 Toturial,3.4.1 版本需要做一点小修改,代码如下。

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
// Get a new frame
Mat frame = inputFrame.rgba();
Imgproc.cvtColor(frame, frame, Imgproc.COLOR_RGBA2RGB);

// Forward image through network.
Mat blob = Dnn.blobFromImage(frame, IN_SCALE_FACTOR,
new Size(IN_WIDTH, IN_HEIGHT),
new Scalar(MEAN_VAL, MEAN_VAL, MEAN_VAL), false, false);
mNet.setInput(blob);
Mat detections = mNet.forward();

...
}

下面有个演示视频,手机摄像头现实场景的图像识别,输出结果的标注代码稍微改了一下,看起来更加明显一点。MobileNetSSD 模型的物体较少大概 20 个,所以有些目标识别可能会不对,但这不是问题换个模型就可以。

参考资料

MobileNet https://arxiv.org/abs/1704.04861
Caffe https://caffe.berkeleyvision.org/
OpenCV DNN https://github.com/opencv/opencv/tree/master/samples/dnn

最近更新 2018-03-21