1*89c4ff92SAndroid Build Coastguard Worker# Object Detection Example 2*89c4ff92SAndroid Build Coastguard Worker 3*89c4ff92SAndroid Build Coastguard Worker## Introduction 4*89c4ff92SAndroid Build Coastguard WorkerThis is a sample code showing object detection using Arm NN in two different modes: 5*89c4ff92SAndroid Build Coastguard Worker1. Utilizing public Arm NN C++ API. 6*89c4ff92SAndroid Build Coastguard Worker2. Utilizing Tensorflow lite delegate file mechanism together with Armnn delegate file. 7*89c4ff92SAndroid Build Coastguard Worker 8*89c4ff92SAndroid Build Coastguard WorkerThe compiled application can take 9*89c4ff92SAndroid Build Coastguard Worker 10*89c4ff92SAndroid Build Coastguard Worker * a video file 11*89c4ff92SAndroid Build Coastguard Worker 12*89c4ff92SAndroid Build Coastguard Workeras input and 13*89c4ff92SAndroid Build Coastguard Worker * save a video file 14*89c4ff92SAndroid Build Coastguard Worker * or output video stream to the window 15*89c4ff92SAndroid Build Coastguard Worker 16*89c4ff92SAndroid Build Coastguard Workerwith detections shown in bounding boxes, class labels and confidence. 17*89c4ff92SAndroid Build Coastguard Worker 18*89c4ff92SAndroid Build Coastguard Worker## Dependencies 19*89c4ff92SAndroid Build Coastguard Worker 20*89c4ff92SAndroid Build Coastguard WorkerThis example utilizes OpenCV functions to capture and output video data. 21*89c4ff92SAndroid Build Coastguard Worker1. Public Arm NN C++ API is provided by Arm NN library. 22*89c4ff92SAndroid Build Coastguard Worker2. For Delegate file mode following dependencies exist: 23*89c4ff92SAndroid Build Coastguard Worker2.1 Tensorflow version 2.10 24*89c4ff92SAndroid Build Coastguard Worker2.2 Flatbuffers version 2.0.6 25*89c4ff92SAndroid Build Coastguard Worker2.3 Arm NN delegate library 26*89c4ff92SAndroid Build Coastguard Worker 27*89c4ff92SAndroid Build Coastguard Worker## System 28*89c4ff92SAndroid Build Coastguard Worker 29*89c4ff92SAndroid Build Coastguard WorkerThis example was created on Ubuntu 20.04 with gcc and g++ version 9. 30*89c4ff92SAndroid Build Coastguard WorkerIf encountered any compiler errors while running with a different compiler version, you can install version 9 with: 31*89c4ff92SAndroid Build Coastguard Worker```commandline 32*89c4ff92SAndroid Build Coastguard Workersudo apt install gcc-9 g++-9 33*89c4ff92SAndroid Build Coastguard Worker``` 34*89c4ff92SAndroid Build Coastguard Workerand add to every cmake command those compiler flags: 35*89c4ff92SAndroid Build Coastguard Worker-DCMAKE_C_COMPILER=gcc-9 -DCMAKE_CXX_COMPILER=g++-9 36*89c4ff92SAndroid Build Coastguard Worker 37*89c4ff92SAndroid Build Coastguard Worker### Arm NN 38*89c4ff92SAndroid Build Coastguard Worker 39*89c4ff92SAndroid Build Coastguard WorkerObject detection example build system does not trigger Arm NN compilation. Thus, before building the application, 40*89c4ff92SAndroid Build Coastguard Workerplease ensure that Arm NN libraries and header files are available on your build platform. 41*89c4ff92SAndroid Build Coastguard WorkerThe application executable binary dynamically links with the following Arm NN libraries: 42*89c4ff92SAndroid Build Coastguard Worker* libarmnn.so 43*89c4ff92SAndroid Build Coastguard WorkerFor Arm NN public C++ API mode: 44*89c4ff92SAndroid Build Coastguard Worker* libarmnnTfLiteParser.so 45*89c4ff92SAndroid Build Coastguard WorkerFor Delegate file mode: 46*89c4ff92SAndroid Build Coastguard Worker* libarmnnDelegate.so 47*89c4ff92SAndroid Build Coastguard Worker 48*89c4ff92SAndroid Build Coastguard WorkerPre compiled Arm NN libraries can be downloaded from https://github.com/ARM-software/armnn/releases/download/v21.11/ArmNN-linux-aarch64.tar.gz 49*89c4ff92SAndroid Build Coastguard Workerthe "lib" and "include" directories should be taken together. 50*89c4ff92SAndroid Build Coastguard Worker 51*89c4ff92SAndroid Build Coastguard WorkerThe build script searches for available Arm NN libraries in the following order: 52*89c4ff92SAndroid Build Coastguard Worker1. Inside custom user directory specified by ARMNN_LIB_DIR cmake option. 53*89c4ff92SAndroid Build Coastguard Worker2. Inside the current Arm NN repository, assuming that Arm NN was built following [this instructions](../../BuildGuideCrossCompilation.md). 54*89c4ff92SAndroid Build Coastguard Worker3. Inside default locations for system libraries, assuming Arm NN was installed from deb packages. 55*89c4ff92SAndroid Build Coastguard Worker 56*89c4ff92SAndroid Build Coastguard WorkerArm NN header files will be searched in parent directory of found libraries files under `include` directory, i.e. 57*89c4ff92SAndroid Build Coastguard Workerlibraries found in `/usr/lib` or `/usr/lib64` and header files in `/usr/include` (or `${ARMNN_LIB_DIR}/include`). 58*89c4ff92SAndroid Build Coastguard Worker 59*89c4ff92SAndroid Build Coastguard WorkerPlease see [find_armnn.cmake](./cmake/find_armnn.cmake) for implementation details. 60*89c4ff92SAndroid Build Coastguard Worker 61*89c4ff92SAndroid Build Coastguard Worker### OpenCV 62*89c4ff92SAndroid Build Coastguard Worker 63*89c4ff92SAndroid Build Coastguard WorkerThis application uses [OpenCV (Open Source Computer Vision Library)](https://opencv.org/) for video stream processing. 64*89c4ff92SAndroid Build Coastguard WorkerYour host platform may have OpenCV available through linux package manager. If this is the case, please install it using standard way. 65*89c4ff92SAndroid Build Coastguard Worker```commandline 66*89c4ff92SAndroid Build Coastguard Workersudo apt install python3-opencv 67*89c4ff92SAndroid Build Coastguard Worker``` 68*89c4ff92SAndroid Build Coastguard WorkerIf not, our build system has a script to download and cross-compile required OpenCV modules 69*89c4ff92SAndroid Build Coastguard Workeras well as [FFMPEG](https://ffmpeg.org/) and [x264 encoder](https://www.videolan.org/developers/x264.html) libraries. 70*89c4ff92SAndroid Build Coastguard WorkerThe latter will build limited OpenCV functionality and application will support only video file input and video file output 71*89c4ff92SAndroid Build Coastguard Workerway of working. Displaying video frames in a window requires building OpenCV with GTK and OpenGL support. 72*89c4ff92SAndroid Build Coastguard Worker 73*89c4ff92SAndroid Build Coastguard WorkerThe application executable binary dynamically links with the following OpenCV libraries: 74*89c4ff92SAndroid Build Coastguard Worker* libopencv_core.so.4.0.0 75*89c4ff92SAndroid Build Coastguard Worker* libopencv_imgproc.so.4.0.0 76*89c4ff92SAndroid Build Coastguard Worker* libopencv_imgcodecs.so.4.0.0 77*89c4ff92SAndroid Build Coastguard Worker* libopencv_videoio.so.4.0.0 78*89c4ff92SAndroid Build Coastguard Worker* libopencv_video.so.4.0.0 79*89c4ff92SAndroid Build Coastguard Worker* libopencv_highgui.so.4.0.0 80*89c4ff92SAndroid Build Coastguard Worker 81*89c4ff92SAndroid Build Coastguard Workerand transitively depends on: 82*89c4ff92SAndroid Build Coastguard Worker* libavcodec.so (FFMPEG) 83*89c4ff92SAndroid Build Coastguard Worker* libavformat.so (FFMPEG) 84*89c4ff92SAndroid Build Coastguard Worker* libavutil.so (FFMPEG) 85*89c4ff92SAndroid Build Coastguard Worker* libswscale.so (FFMPEG) 86*89c4ff92SAndroid Build Coastguard Worker* libx264.so (x264) 87*89c4ff92SAndroid Build Coastguard Worker 88*89c4ff92SAndroid Build Coastguard WorkerThe application searches for above libraries in the following order: 89*89c4ff92SAndroid Build Coastguard Worker1. Inside custom user directory specified by OPENCV_LIB_DIR cmake option. 90*89c4ff92SAndroid Build Coastguard Worker2. Inside default locations for system libraries. 91*89c4ff92SAndroid Build Coastguard Worker 92*89c4ff92SAndroid Build Coastguard WorkerIf no OpenCV libraries were found, the cross-compilation build is extended with x264, ffmpeg and OpenCV compilation steps. 93*89c4ff92SAndroid Build Coastguard Worker 94*89c4ff92SAndroid Build Coastguard WorkerNote: Native build does not add third party libraries to compilation. 95*89c4ff92SAndroid Build Coastguard Worker 96*89c4ff92SAndroid Build Coastguard WorkerPlease see [find_opencv.cmake](./cmake/find_opencv.cmake) for implementation details. 97*89c4ff92SAndroid Build Coastguard Worker 98*89c4ff92SAndroid Build Coastguard Worker### Tensorflow Lite (Needed only in delegate file mode) 99*89c4ff92SAndroid Build Coastguard Worker 100*89c4ff92SAndroid Build Coastguard WorkerThis application uses [Tensorflow Lite)](https://www.tensorflow.org/) version 2.10 for demonstrating use of 'armnnDelegate'. 101*89c4ff92SAndroid Build Coastguard WorkerarmnnDelegate is a library for accelerating certain TensorFlow Lite operators on Arm hardware by providing 102*89c4ff92SAndroid Build Coastguard Workerthe TensorFlow Lite interpreter with an alternative implementation of the operators via its delegation mechanism. 103*89c4ff92SAndroid Build Coastguard WorkerYou may clone and build Tensorflow lite and provide the path to its root and output library directories through the cmake 104*89c4ff92SAndroid Build Coastguard Workerflags TENSORFLOW_ROOT and TFLITE_LIB_ROOT respectively. 105*89c4ff92SAndroid Build Coastguard WorkerFor implementation details see the scripts FindTfLite.cmake and FindTfLiteSrc.cmake 106*89c4ff92SAndroid Build Coastguard Worker 107*89c4ff92SAndroid Build Coastguard WorkerThe application links with the Tensorflow lite library libtensorflow-lite.a 108*89c4ff92SAndroid Build Coastguard Worker 109*89c4ff92SAndroid Build Coastguard Worker#### Download and build Tensorflow Lite version 2.10 110*89c4ff92SAndroid Build Coastguard WorkerExample for Tensorflow Lite native compilation 111*89c4ff92SAndroid Build Coastguard Worker```commandline 112*89c4ff92SAndroid Build Coastguard Workersudo apt install build-essential 113*89c4ff92SAndroid Build Coastguard Workergit clone https://github.com/tensorflow/tensorflow.git 114*89c4ff92SAndroid Build Coastguard Workercd tensorflow/tensorflow 115*89c4ff92SAndroid Build Coastguard Workergit checkout 359c3cdfc5fabac82b3c70b3b6de2b0a8c16874f #Tensorflow 2.10 116*89c4ff92SAndroid Build Coastguard Workermkdir build && cd build 117*89c4ff92SAndroid Build Coastguard Workercmake ../lite -DTFLITE_ENABLE_XNNPACK=OFF 118*89c4ff92SAndroid Build Coastguard Workermake 119*89c4ff92SAndroid Build Coastguard Worker``` 120*89c4ff92SAndroid Build Coastguard Worker 121*89c4ff92SAndroid Build Coastguard Worker### Flatbuffers (needed only in delegate file mode) 122*89c4ff92SAndroid Build Coastguard Worker 123*89c4ff92SAndroid Build Coastguard WorkerThis application uses [Flatbuffers)](https://google.github.io/flatbuffers/) version 1.12.0 for serialization 124*89c4ff92SAndroid Build Coastguard WorkerYou may clone and build Flatbuffers and provide the path to its root directory through the cmake 125*89c4ff92SAndroid Build Coastguard Workerflag FLATBUFFERS_ROOT. 126*89c4ff92SAndroid Build Coastguard WorkerPlease see [FindFlatbuffers.cmake] for implementation details. 127*89c4ff92SAndroid Build Coastguard Worker 128*89c4ff92SAndroid Build Coastguard WorkerThe application links with the Flatbuffers library libflatbuffers.a 129*89c4ff92SAndroid Build Coastguard Worker 130*89c4ff92SAndroid Build Coastguard Worker#### Download and build flatbuffers version 2.0.6 131*89c4ff92SAndroid Build Coastguard WorkerExample for flatbuffer native compilation 132*89c4ff92SAndroid Build Coastguard Worker```commandline 133*89c4ff92SAndroid Build Coastguard Workerwget https://github.com/google/flatbuffers/archive/v2.0.6.tar.gz 134*89c4ff92SAndroid Build Coastguard Workertar xf v2.0.6.tar.gz 135*89c4ff92SAndroid Build Coastguard Workercd flatbuffers-2.0.6 136*89c4ff92SAndroid Build Coastguard Workermkdir install && cd install 137*89c4ff92SAndroid Build Coastguard Workercmake .. -DCMAKE_INSTALL_PREFIX:PATH=`pwd` 138*89c4ff92SAndroid Build Coastguard Workermake install 139*89c4ff92SAndroid Build Coastguard Worker``` 140*89c4ff92SAndroid Build Coastguard Worker 141*89c4ff92SAndroid Build Coastguard Worker## Building 142*89c4ff92SAndroid Build Coastguard WorkerThere are two flows for building this application: 143*89c4ff92SAndroid Build Coastguard Worker* native build on a host platform, 144*89c4ff92SAndroid Build Coastguard Worker* cross-compilation for a Arm-based host platform. 145*89c4ff92SAndroid Build Coastguard Worker 146*89c4ff92SAndroid Build Coastguard Worker### Build Options 147*89c4ff92SAndroid Build Coastguard Worker 148*89c4ff92SAndroid Build Coastguard Worker* CMAKE_TOOLCHAIN_FILE - choose one of the available cross-compilation toolchain files: 149*89c4ff92SAndroid Build Coastguard Worker * `cmake/aarch64-toolchain.cmake` 150*89c4ff92SAndroid Build Coastguard Worker * `cmake/arm-linux-gnueabihf-toolchain.cmake` 151*89c4ff92SAndroid Build Coastguard Worker* ARMNN_LIB_DIR - point to the custom location of the Arm NN libs and headers. 152*89c4ff92SAndroid Build Coastguard Worker* OPENCV_LIB_DIR - point to the custom location of the OpenCV libs and headers. 153*89c4ff92SAndroid Build Coastguard Worker* BUILD_UNIT_TESTS - set to `1` to build tests. Additionally to the main application, `object_detection_example-tests` 154*89c4ff92SAndroid Build Coastguard Workerunit tests executable will be created. 155*89c4ff92SAndroid Build Coastguard Worker 156*89c4ff92SAndroid Build Coastguard Worker* For the Delegate file mode: 157*89c4ff92SAndroid Build Coastguard Worker* USE_ARMNN_DELEGATE - set to True to build the application with Tflite and delegate file mode. default is False. 158*89c4ff92SAndroid Build Coastguard Worker* TFLITE_LIB_ROOT - point to the custom location of Tflite lib 159*89c4ff92SAndroid Build Coastguard Worker* TENSORFLOW_ROOT - point to the custom location of Tensorflow root directory 160*89c4ff92SAndroid Build Coastguard Worker* FLATBUFFERS_ROOT - point to the custom location of Flatbuffers root directory 161*89c4ff92SAndroid Build Coastguard Worker 162*89c4ff92SAndroid Build Coastguard Worker### Native Build 163*89c4ff92SAndroid Build Coastguard WorkerTo build this application on a host platform, firstly ensure that required dependencies are installed: 164*89c4ff92SAndroid Build Coastguard WorkerFor example, for raspberry PI: 165*89c4ff92SAndroid Build Coastguard Worker```commandline 166*89c4ff92SAndroid Build Coastguard Workersudo apt-get update 167*89c4ff92SAndroid Build Coastguard Workersudo apt-get -yq install pkg-config 168*89c4ff92SAndroid Build Coastguard Workersudo apt-get -yq install libgtk2.0-dev zlib1g-dev libjpeg-dev libpng-dev libxvidcore-dev libx264-dev 169*89c4ff92SAndroid Build Coastguard Workersudo apt-get -yq install libavcodec-dev libavformat-dev libswscale-dev ocl-icd-opencl-dev 170*89c4ff92SAndroid Build Coastguard Worker``` 171*89c4ff92SAndroid Build Coastguard Worker 172*89c4ff92SAndroid Build Coastguard WorkerTo build demo application, create a build directory: 173*89c4ff92SAndroid Build Coastguard Worker```commandline 174*89c4ff92SAndroid Build Coastguard Workermkdir build 175*89c4ff92SAndroid Build Coastguard Workercd build 176*89c4ff92SAndroid Build Coastguard Worker``` 177*89c4ff92SAndroid Build Coastguard WorkerIf you have already installed Arm NN and OpenCV: 178*89c4ff92SAndroid Build Coastguard Worker 179*89c4ff92SAndroid Build Coastguard WorkerInside build directory, run cmake and make commands: 180*89c4ff92SAndroid Build Coastguard Worker```commandline 181*89c4ff92SAndroid Build Coastguard Workercmake .. 182*89c4ff92SAndroid Build Coastguard Workermake 183*89c4ff92SAndroid Build Coastguard Worker``` 184*89c4ff92SAndroid Build Coastguard WorkerThis will build the following in bin directory: 185*89c4ff92SAndroid Build Coastguard Worker* object_detection_example - application executable 186*89c4ff92SAndroid Build Coastguard Worker 187*89c4ff92SAndroid Build Coastguard WorkerIf you have custom Arm NN and OpenCV location, use `OPENCV_LIB_DIR` and `ARMNN_LIB_DIR` options: 188*89c4ff92SAndroid Build Coastguard Worker```commandline 189*89c4ff92SAndroid Build Coastguard Workercmake -DARMNN_LIB_DIR=/path/to/armnn -DOPENCV_LIB_DIR=/path/to/opencv .. 190*89c4ff92SAndroid Build Coastguard Workermake 191*89c4ff92SAndroid Build Coastguard Worker``` 192*89c4ff92SAndroid Build Coastguard Worker 193*89c4ff92SAndroid Build Coastguard WorkerIf you have build with Delegate file mode and have custom Arm NN, Tflite, and Flatbuffers locations, 194*89c4ff92SAndroid Build Coastguard Workeruse the USE_ARMNN_DELEGATE flag together with `TFLITE_LIB_ROOT`, `TENSORFLOW_ROOT`, `FLATBUFFERS_ROOT` and 195*89c4ff92SAndroid Build Coastguard Worker`ARMNN_LIB_DIR` options: 196*89c4ff92SAndroid Build Coastguard Worker```commandline 197*89c4ff92SAndroid Build Coastguard Workercmake -DARMNN_LIB_DIR=/path/to/armnn/build/lib/ -DUSE_ARMNN_DELEGATE=True -DTFLITE_LIB_ROOT=/path/to/tensorflow/ 198*89c4ff92SAndroid Build Coastguard Worker -DTENSORFLOW_ROOT=/path/to/tensorflow/ -DFLATBUFFERS_ROOT=/path/to/flatbuffers/ .. 199*89c4ff92SAndroid Build Coastguard Workermake 200*89c4ff92SAndroid Build Coastguard Worker``` 201*89c4ff92SAndroid Build Coastguard Worker 202*89c4ff92SAndroid Build Coastguard Worker### Cross-compilation 203*89c4ff92SAndroid Build Coastguard Worker 204*89c4ff92SAndroid Build Coastguard WorkerThis section will explain how to cross-compile the application and dependencies on a Linux x86 machine 205*89c4ff92SAndroid Build Coastguard Workerfor arm host platforms. 206*89c4ff92SAndroid Build Coastguard Worker 207*89c4ff92SAndroid Build Coastguard WorkerYou will require working cross-compilation toolchain supported by your host platform. For raspberry Pi 3 and 4 with glibc 208*89c4ff92SAndroid Build Coastguard Workerruntime version 2.28, the following toolchains were successfully used: 209*89c4ff92SAndroid Build Coastguard Worker* https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/ 210*89c4ff92SAndroid Build Coastguard Worker* https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabihf/ 211*89c4ff92SAndroid Build Coastguard Worker 212*89c4ff92SAndroid Build Coastguard WorkerChoose aarch64-linux-gnu if `lscpu` command shows architecture as aarch64 or arm-linux-gnueabihf if detected 213*89c4ff92SAndroid Build Coastguard Workerarchitecture is armv71. 214*89c4ff92SAndroid Build Coastguard Worker 215*89c4ff92SAndroid Build Coastguard WorkerYou can check runtime version on your host platform by running: 216*89c4ff92SAndroid Build Coastguard Worker``` 217*89c4ff92SAndroid Build Coastguard Workerldd --version 218*89c4ff92SAndroid Build Coastguard Worker``` 219*89c4ff92SAndroid Build Coastguard WorkerOn **build machine**, install C and C++ cross compiler toolchains and add them to the PATH variable. 220*89c4ff92SAndroid Build Coastguard Worker 221*89c4ff92SAndroid Build Coastguard WorkerInstall package dependencies: 222*89c4ff92SAndroid Build Coastguard Worker```commandline 223*89c4ff92SAndroid Build Coastguard Workersudo apt-get update 224*89c4ff92SAndroid Build Coastguard Workersudo apt-get -yq install pkg-config 225*89c4ff92SAndroid Build Coastguard Worker``` 226*89c4ff92SAndroid Build Coastguard WorkerPackage config is required by OpenCV build to discover FFMPEG libs. 227*89c4ff92SAndroid Build Coastguard Worker 228*89c4ff92SAndroid Build Coastguard WorkerTo build demo application, create a build directory: 229*89c4ff92SAndroid Build Coastguard Worker```commandline 230*89c4ff92SAndroid Build Coastguard Workermkdir build 231*89c4ff92SAndroid Build Coastguard Workercd build 232*89c4ff92SAndroid Build Coastguard Worker``` 233*89c4ff92SAndroid Build Coastguard WorkerInside build directory, run cmake and make commands: 234*89c4ff92SAndroid Build Coastguard Worker 235*89c4ff92SAndroid Build Coastguard Worker**Arm 32bit** 236*89c4ff92SAndroid Build Coastguard Worker```commandline 237*89c4ff92SAndroid Build Coastguard Workercmake -DARMNN_LIB_DIR=<path-to-armnn-libs> -DCMAKE_TOOLCHAIN_FILE=cmake/arm-linux-gnueabihf-toolchain.cmake .. 238*89c4ff92SAndroid Build Coastguard Workermake 239*89c4ff92SAndroid Build Coastguard Worker``` 240*89c4ff92SAndroid Build Coastguard Worker**Arm 64bit** 241*89c4ff92SAndroid Build Coastguard Worker```commandline 242*89c4ff92SAndroid Build Coastguard Workercmake -DARMNN_LIB_DIR=<path-to-armnn-libs> -DCMAKE_TOOLCHAIN_FILE=cmake/aarch64-toolchain.cmake .. 243*89c4ff92SAndroid Build Coastguard Workermake 244*89c4ff92SAndroid Build Coastguard Worker``` 245*89c4ff92SAndroid Build Coastguard Worker 246*89c4ff92SAndroid Build Coastguard WorkerAdd `-j` flag to the make command to run compilation in multiple threads. 247*89c4ff92SAndroid Build Coastguard Worker 248*89c4ff92SAndroid Build Coastguard WorkerFrom the build directory, copy the following to the host platform: 249*89c4ff92SAndroid Build Coastguard Worker* bin directory - contains object_detection_example executable, 250*89c4ff92SAndroid Build Coastguard Worker* lib directory - contains cross-compiled OpenCV, ffmpeg, x264 libraries, 251*89c4ff92SAndroid Build Coastguard Worker* Your Arm NN libs used during compilation. 252*89c4ff92SAndroid Build Coastguard Worker 253*89c4ff92SAndroid Build Coastguard WorkerThe full list of libs after cross-compilation to copy on your board: 254*89c4ff92SAndroid Build Coastguard Worker``` 255*89c4ff92SAndroid Build Coastguard Workerlibarmnn.so 256*89c4ff92SAndroid Build Coastguard Workerlibarmnn.so.31 257*89c4ff92SAndroid Build Coastguard Workerlibarmnn.so.31.0 258*89c4ff92SAndroid Build Coastguard WorkerFor Arm NN public C++ API mode: 259*89c4ff92SAndroid Build Coastguard WorkerlibarmnnTfLiteParser.so 260*89c4ff92SAndroid Build Coastguard WorkerlibarmnnTfLiteParser.so.24.4 261*89c4ff92SAndroid Build Coastguard Workerend 262*89c4ff92SAndroid Build Coastguard WorkerFor Delegate file mode: 263*89c4ff92SAndroid Build Coastguard WorkerlibarmnnDelegate.so 264*89c4ff92SAndroid Build Coastguard WorkerlibarmnnDelegate.so.25 265*89c4ff92SAndroid Build Coastguard WorkerlibarmnnDelegate.so.25.0 266*89c4ff92SAndroid Build Coastguard Workerlibtensorflow-lite.a 267*89c4ff92SAndroid Build Coastguard Workerlibflatbuffers.a 268*89c4ff92SAndroid Build Coastguard Workerend 269*89c4ff92SAndroid Build Coastguard Worker 270*89c4ff92SAndroid Build Coastguard Workerlibavcodec.so 271*89c4ff92SAndroid Build Coastguard Workerlibavcodec.so.58 272*89c4ff92SAndroid Build Coastguard Workerlibavcodec.so.58.54.100 273*89c4ff92SAndroid Build Coastguard Workerlibavdevice.so 274*89c4ff92SAndroid Build Coastguard Workerlibavdevice.so.58 275*89c4ff92SAndroid Build Coastguard Workerlibavdevice.so.58.8.100 276*89c4ff92SAndroid Build Coastguard Workerlibavfilter.so 277*89c4ff92SAndroid Build Coastguard Workerlibavfilter.so.7 278*89c4ff92SAndroid Build Coastguard Workerlibavfilter.so.7.57.100 279*89c4ff92SAndroid Build Coastguard Workerlibavformat.so 280*89c4ff92SAndroid Build Coastguard Workerlibavformat.so.58 281*89c4ff92SAndroid Build Coastguard Workerlibavformat.so.58.29.100 282*89c4ff92SAndroid Build Coastguard Workerlibavutil.so 283*89c4ff92SAndroid Build Coastguard Workerlibavutil.so.56 284*89c4ff92SAndroid Build Coastguard Workerlibavutil.so.56.31.100 285*89c4ff92SAndroid Build Coastguard Workerlibopencv_core.so 286*89c4ff92SAndroid Build Coastguard Workerlibopencv_core.so.4.0 287*89c4ff92SAndroid Build Coastguard Workerlibopencv_core.so.4.0.0 288*89c4ff92SAndroid Build Coastguard Workerlibopencv_highgui.so 289*89c4ff92SAndroid Build Coastguard Workerlibopencv_highgui.so.4.0 290*89c4ff92SAndroid Build Coastguard Workerlibopencv_highgui.so.4.0.0 291*89c4ff92SAndroid Build Coastguard Workerlibopencv_imgcodecs.so 292*89c4ff92SAndroid Build Coastguard Workerlibopencv_imgcodecs.so.4.0 293*89c4ff92SAndroid Build Coastguard Workerlibopencv_imgcodecs.so.4.0.0 294*89c4ff92SAndroid Build Coastguard Workerlibopencv_imgproc.so 295*89c4ff92SAndroid Build Coastguard Workerlibopencv_imgproc.so.4.0 296*89c4ff92SAndroid Build Coastguard Workerlibopencv_imgproc.so.4.0.0 297*89c4ff92SAndroid Build Coastguard Workerlibopencv_video.so 298*89c4ff92SAndroid Build Coastguard Workerlibopencv_video.so.4.0 299*89c4ff92SAndroid Build Coastguard Workerlibopencv_video.so.4.0.0 300*89c4ff92SAndroid Build Coastguard Workerlibopencv_videoio.so 301*89c4ff92SAndroid Build Coastguard Workerlibopencv_videoio.so.4.0 302*89c4ff92SAndroid Build Coastguard Workerlibopencv_videoio.so.4.0.0 303*89c4ff92SAndroid Build Coastguard Workerlibpostproc.so 304*89c4ff92SAndroid Build Coastguard Workerlibpostproc.so.55 305*89c4ff92SAndroid Build Coastguard Workerlibpostproc.so.55.5.100 306*89c4ff92SAndroid Build Coastguard Workerlibswresample.a 307*89c4ff92SAndroid Build Coastguard Workerlibswresample.so 308*89c4ff92SAndroid Build Coastguard Workerlibswresample.so.3 309*89c4ff92SAndroid Build Coastguard Workerlibswresample.so.3.5.100 310*89c4ff92SAndroid Build Coastguard Workerlibswscale.so 311*89c4ff92SAndroid Build Coastguard Workerlibswscale.so.5 312*89c4ff92SAndroid Build Coastguard Workerlibswscale.so.5.5.100 313*89c4ff92SAndroid Build Coastguard Workerlibx264.so 314*89c4ff92SAndroid Build Coastguard Workerlibx264.so.160 315*89c4ff92SAndroid Build Coastguard Worker``` 316*89c4ff92SAndroid Build Coastguard Worker## Executing 317*89c4ff92SAndroid Build Coastguard Worker 318*89c4ff92SAndroid Build Coastguard WorkerOnce the application executable is built, it can be executed with the following options: 319*89c4ff92SAndroid Build Coastguard Worker* --video-file-path: Path to the video file to run object detection on **[REQUIRED]** 320*89c4ff92SAndroid Build Coastguard Worker* --model-file-path: Path to the Object Detection model to use **[REQUIRED]** 321*89c4ff92SAndroid Build Coastguard Worker* --label-path: Path to the label set for the provided model file **[REQUIRED]** 322*89c4ff92SAndroid Build Coastguard Worker* --model-name: The name of the model being used. Accepted options: SSD_MOBILE | YOLO_V3_TINY **[REQUIRED]** 323*89c4ff92SAndroid Build Coastguard Worker* --output-video-file-path: Path to the output video file with detections added in. Defaults to /tmp/output.avi 324*89c4ff92SAndroid Build Coastguard Worker **[OPTIONAL]** 325*89c4ff92SAndroid Build Coastguard Worker* --preferred-backends: Takes the preferred backends in preference order, separated by comma. 326*89c4ff92SAndroid Build Coastguard Worker For example: CpuAcc,GpuAcc,CpuRef. Accepted options: [CpuAcc, CpuRef, GpuAcc]. 327*89c4ff92SAndroid Build Coastguard Worker Defaults to CpuRef **[OPTIONAL]** 328*89c4ff92SAndroid Build Coastguard Worker* --profiling_enabled: Enabling this option will print important ML related milestones timing 329*89c4ff92SAndroid Build Coastguard Worker information in micro-seconds. By default, this option is disabled. 330*89c4ff92SAndroid Build Coastguard Worker Accepted options are true/false **[OPTIONAL]** 331*89c4ff92SAndroid Build Coastguard Worker 332*89c4ff92SAndroid Build Coastguard Worker### Object Detection on a supplied video file 333*89c4ff92SAndroid Build Coastguard Worker 334*89c4ff92SAndroid Build Coastguard WorkerTo run object detection on a supplied video file and output result to a video file: 335*89c4ff92SAndroid Build Coastguard Worker```commandline 336*89c4ff92SAndroid Build Coastguard WorkerLD_LIBRARY_PATH=/path/to/armnn/libs:/path/to/opencv/libs ./object_detection_example --label-path /path/to/labels/file 337*89c4ff92SAndroid Build Coastguard Worker --video-file-path /path/to/video/file --model-file-path /path/to/model/file 338*89c4ff92SAndroid Build Coastguard Worker --model-name [YOLO_V3_TINY | SSD_MOBILE] --output-video-file-path /path/to/output/file 339*89c4ff92SAndroid Build Coastguard Worker``` 340*89c4ff92SAndroid Build Coastguard Worker 341*89c4ff92SAndroid Build Coastguard WorkerTo run object detection on a supplied video file and output result to a window gui: 342*89c4ff92SAndroid Build Coastguard Worker```commandline 343*89c4ff92SAndroid Build Coastguard WorkerLD_LIBRARY_PATH=/path/to/armnn/libs:/path/to/opencv/libs ./object_detection_example --label-path /path/to/labels/file 344*89c4ff92SAndroid Build Coastguard Worker --video-file-path /path/to/video/file --model-file-path /path/to/model/file 345*89c4ff92SAndroid Build Coastguard Worker --model-name [YOLO_V3_TINY | SSD_MOBILE] 346*89c4ff92SAndroid Build Coastguard Worker``` 347*89c4ff92SAndroid Build Coastguard Worker 348*89c4ff92SAndroid Build Coastguard WorkerThis application has been verified to work against the MobileNet SSD and the YOLO V3 tiny models, which can be downloaded along with their label sets from the Arm Model Zoo: 349*89c4ff92SAndroid Build Coastguard Worker* https://github.com/ARM-software/ML-zoo/tree/master/models/object_detection/ssd_mobilenet_v1 350*89c4ff92SAndroid Build Coastguard Worker* https://github.com/ARM-software/ML-zoo/tree/master/models/object_detection/yolo_v3_tiny 351*89c4ff92SAndroid Build Coastguard Worker 352*89c4ff92SAndroid Build Coastguard Worker--- 353*89c4ff92SAndroid Build Coastguard Worker 354*89c4ff92SAndroid Build Coastguard Worker# Application Overview 355*89c4ff92SAndroid Build Coastguard WorkerThis section provides a walkthrough of the application, explaining in detail the steps: 356*89c4ff92SAndroid Build Coastguard Worker1. Initialisation 357*89c4ff92SAndroid Build Coastguard Worker 1. Reading from Video Source 358*89c4ff92SAndroid Build Coastguard Worker 2. Preparing Labels and Model Specific Functions 359*89c4ff92SAndroid Build Coastguard Worker2. Creating a Network (two modes are available) 360*89c4ff92SAndroid Build Coastguard Worker a. Armnn C++ API mode: 361*89c4ff92SAndroid Build Coastguard Worker 1. Creating Parser and Importing Graph 362*89c4ff92SAndroid Build Coastguard Worker 2. Optimizing Graph for Compute Device 363*89c4ff92SAndroid Build Coastguard Worker 3. Creating Input and Output Binding Information 364*89c4ff92SAndroid Build Coastguard Worker b. using Tflite and delegate file mode: 365*89c4ff92SAndroid Build Coastguard Worker 1. Building a Model and creating Interpreter 366*89c4ff92SAndroid Build Coastguard Worker 2. Creating Arm NN delegate file 367*89c4ff92SAndroid Build Coastguard Worker 3. Registering the Arm NN delegate file to the Interpreter 368*89c4ff92SAndroid Build Coastguard Worker3. Object detection pipeline 369*89c4ff92SAndroid Build Coastguard Worker 1. Pre-processing the Captured Frame 370*89c4ff92SAndroid Build Coastguard Worker 2. Making Input and Output Tensors 371*89c4ff92SAndroid Build Coastguard Worker 3. Executing Inference 372*89c4ff92SAndroid Build Coastguard Worker 4. Postprocessing 373*89c4ff92SAndroid Build Coastguard Worker 5. Decoding and Processing Inference Output 374*89c4ff92SAndroid Build Coastguard Worker 6. Drawing Bounding Boxes 375*89c4ff92SAndroid Build Coastguard Worker 376*89c4ff92SAndroid Build Coastguard Worker 377*89c4ff92SAndroid Build Coastguard Worker### Initialisation 378*89c4ff92SAndroid Build Coastguard Worker 379*89c4ff92SAndroid Build Coastguard Worker##### Reading from Video Source 380*89c4ff92SAndroid Build Coastguard WorkerAfter parsing user arguments, the chosen video file or stream is loaded into an OpenCV `cv::VideoCapture` object. 381*89c4ff92SAndroid Build Coastguard WorkerWe use [`IFrameReader`](./include/IFrameReader.hpp) interface and OpenCV specific implementation 382*89c4ff92SAndroid Build Coastguard Worker[`CvVideoFrameReader`](./include/CvVideoFrameReader.hpp) in our main function to capture frames from the source using the 383*89c4ff92SAndroid Build Coastguard Worker`ReadFrame()` function. 384*89c4ff92SAndroid Build Coastguard Worker 385*89c4ff92SAndroid Build Coastguard WorkerThe `CvVideoFrameReader` object also tells us information about the input video. Using this information and application 386*89c4ff92SAndroid Build Coastguard Workerarguments, we create one of the implementations of the [`IFrameOutput`](./include/IFrameOutput.hpp) interface: 387*89c4ff92SAndroid Build Coastguard Worker[`CvVideoFileWriter`](./include/CvVideoFileWriter.hpp) or [`CvWindowOutput`](./include/CvWindowOutput.hpp). 388*89c4ff92SAndroid Build Coastguard WorkerThis object will be used at the end of every loop to write the processed frame to an output video file or gui 389*89c4ff92SAndroid Build Coastguard Workerwindow. 390*89c4ff92SAndroid Build Coastguard Worker`CvVideoFileWriter` uses `cv::VideoWriter` with ffmpeg backend. `CvWindowOutput` makes use of `cv::imshow()` function. 391*89c4ff92SAndroid Build Coastguard Worker 392*89c4ff92SAndroid Build Coastguard WorkerSee `GetFrameSourceAndSink` function in [Main.cpp](./src/Main.cpp) for more details. 393*89c4ff92SAndroid Build Coastguard Worker 394*89c4ff92SAndroid Build Coastguard Worker##### Preparing Labels and Model Specific Functions 395*89c4ff92SAndroid Build Coastguard WorkerIn order to interpret the result of running inference on the loaded network, it is required to load the labels 396*89c4ff92SAndroid Build Coastguard Workerassociated with the model. In the provided example code, the `AssignColourToLabel` function creates a vector of pairs 397*89c4ff92SAndroid Build Coastguard Workerlabel - colour that is ordered according to object class index at the output node of the model. Labels are assigned with 398*89c4ff92SAndroid Build Coastguard Workera randomly generated RGB color. This ensures that each class has a unique color which will prove helpful when plotting 399*89c4ff92SAndroid Build Coastguard Workerthe bounding boxes of various detected objects in a frame. 400*89c4ff92SAndroid Build Coastguard Worker 401*89c4ff92SAndroid Build Coastguard WorkerDepending on the model being used, `CreatePipeline` function returns specific implementation of the object detection 402*89c4ff92SAndroid Build Coastguard Workerpipeline. 403*89c4ff92SAndroid Build Coastguard Worker 404*89c4ff92SAndroid Build Coastguard Worker 405*89c4ff92SAndroid Build Coastguard Worker### There are two ways for Creating the Network. The first is using the Arm NN C++ API, and the second is using 406*89c4ff92SAndroid Build Coastguard Worker### Tflite with Arm NN delegate file 407*89c4ff92SAndroid Build Coastguard Worker 408*89c4ff92SAndroid Build Coastguard Worker#### Creating a Network using the Arm NN C++ API 409*89c4ff92SAndroid Build Coastguard Worker 410*89c4ff92SAndroid Build Coastguard WorkerAll operations with Arm NN and networks are encapsulated in 411*89c4ff92SAndroid Build Coastguard Worker[`ArmnnNetworkExecutor`](./common/include/ArmnnUtils/ArmnnNetworkExecutor.hpp) class. 412*89c4ff92SAndroid Build Coastguard Worker 413*89c4ff92SAndroid Build Coastguard Worker##### Creating Parser and Importing Graph 414*89c4ff92SAndroid Build Coastguard WorkerThe first step with Arm NN SDK is to import a graph from file by using the appropriate parser. 415*89c4ff92SAndroid Build Coastguard Worker 416*89c4ff92SAndroid Build Coastguard WorkerThe Arm NN SDK provides parsers for reading graphs from a variety of model formats. In our application we specifically 417*89c4ff92SAndroid Build Coastguard Workerfocus on `.tflite, .pb, .onnx` models. 418*89c4ff92SAndroid Build Coastguard Worker 419*89c4ff92SAndroid Build Coastguard WorkerBased on the extension of the provided model file, the corresponding parser is created and the network file loaded with 420*89c4ff92SAndroid Build Coastguard Worker`CreateNetworkFromBinaryFile()` method. The parser will handle the creation of the underlying Arm NN graph. 421*89c4ff92SAndroid Build Coastguard Worker 422*89c4ff92SAndroid Build Coastguard WorkerCurrent example accepts tflite format model files, we use `ITfLiteParser`: 423*89c4ff92SAndroid Build Coastguard Worker```c++ 424*89c4ff92SAndroid Build Coastguard Worker#include "armnnTfLiteParser/ITfLiteParser.hpp" 425*89c4ff92SAndroid Build Coastguard Worker 426*89c4ff92SAndroid Build Coastguard WorkerarmnnTfLiteParser::ITfLiteParserPtr parser = armnnTfLiteParser::ITfLiteParser::Create(); 427*89c4ff92SAndroid Build Coastguard Workerarmnn::INetworkPtr network = parser->CreateNetworkFromBinaryFile(modelPath.c_str()); 428*89c4ff92SAndroid Build Coastguard Worker``` 429*89c4ff92SAndroid Build Coastguard Worker 430*89c4ff92SAndroid Build Coastguard Worker##### Optimizing Graph for Compute Device 431*89c4ff92SAndroid Build Coastguard WorkerArm NN supports optimized execution on multiple CPU and GPU devices. Prior to executing a graph, we must select the 432*89c4ff92SAndroid Build Coastguard Workerappropriate device context. We do this by creating a runtime context with default options with `IRuntime()`. 433*89c4ff92SAndroid Build Coastguard Worker 434*89c4ff92SAndroid Build Coastguard WorkerFor example: 435*89c4ff92SAndroid Build Coastguard Worker```c++ 436*89c4ff92SAndroid Build Coastguard Worker#include "armnn/ArmNN.hpp" 437*89c4ff92SAndroid Build Coastguard Worker 438*89c4ff92SAndroid Build Coastguard Workerauto runtime = armnn::IRuntime::Create(armnn::IRuntime::CreationOptions()); 439*89c4ff92SAndroid Build Coastguard Worker``` 440*89c4ff92SAndroid Build Coastguard Worker 441*89c4ff92SAndroid Build Coastguard WorkerWe can optimize the imported graph by specifying a list of backends in order of preference and implement 442*89c4ff92SAndroid Build Coastguard Workerbackend-specific optimizations. The backends are identified by a string unique to the backend, 443*89c4ff92SAndroid Build Coastguard Workerfor example `CpuAcc, GpuAcc, CpuRef`. 444*89c4ff92SAndroid Build Coastguard Worker 445*89c4ff92SAndroid Build Coastguard WorkerFor example: 446*89c4ff92SAndroid Build Coastguard Worker```c++ 447*89c4ff92SAndroid Build Coastguard Workerstd::vector<armnn::BackendId> backends{"CpuAcc", "GpuAcc", "CpuRef"}; 448*89c4ff92SAndroid Build Coastguard Worker``` 449*89c4ff92SAndroid Build Coastguard Worker 450*89c4ff92SAndroid Build Coastguard WorkerInternally and transparently, Arm NN splits the graph into subgraph based on backends, it calls a optimize subgraphs 451*89c4ff92SAndroid Build Coastguard Workerfunction on each of them and, if possible, substitutes the corresponding subgraph in the original graph with 452*89c4ff92SAndroid Build Coastguard Workerits optimized version. 453*89c4ff92SAndroid Build Coastguard Worker 454*89c4ff92SAndroid Build Coastguard WorkerUsing the `Optimize()` function we optimize the graph for inference and load the optimized network onto the compute 455*89c4ff92SAndroid Build Coastguard Workerdevice with `LoadNetwork()`. This function creates the backend-specific workloads 456*89c4ff92SAndroid Build Coastguard Workerfor the layers and a backend specific workload factory which is called to create the workloads. 457*89c4ff92SAndroid Build Coastguard Worker 458*89c4ff92SAndroid Build Coastguard WorkerFor example: 459*89c4ff92SAndroid Build Coastguard Worker```c++ 460*89c4ff92SAndroid Build Coastguard Workerarmnn::IOptimizedNetworkPtr optNet = Optimize(*network, 461*89c4ff92SAndroid Build Coastguard Worker backends, 462*89c4ff92SAndroid Build Coastguard Worker m_Runtime->GetDeviceSpec(), 463*89c4ff92SAndroid Build Coastguard Worker armnn::OptimizerOptions()); 464*89c4ff92SAndroid Build Coastguard Workerstd::string errorMessage; 465*89c4ff92SAndroid Build Coastguard Workerruntime->LoadNetwork(0, std::move(optNet), errorMessage)); 466*89c4ff92SAndroid Build Coastguard Workerstd::cerr << errorMessage << std::endl; 467*89c4ff92SAndroid Build Coastguard Worker``` 468*89c4ff92SAndroid Build Coastguard Worker 469*89c4ff92SAndroid Build Coastguard Worker##### Creating Input and Output Binding Information 470*89c4ff92SAndroid Build Coastguard WorkerParsers can also be used to extract the input information for the network. By calling `GetSubgraphInputTensorNames` 471*89c4ff92SAndroid Build Coastguard Workerwe extract all the input names and, with `GetNetworkInputBindingInfo`, bind the input points of the graph. 472*89c4ff92SAndroid Build Coastguard WorkerFor example: 473*89c4ff92SAndroid Build Coastguard Worker```c++ 474*89c4ff92SAndroid Build Coastguard Workerstd::vector<std::string> inputNames = parser->GetSubgraphInputTensorNames(0); 475*89c4ff92SAndroid Build Coastguard Workerauto inputBindingInfo = parser->GetNetworkInputBindingInfo(0, inputNames[0]); 476*89c4ff92SAndroid Build Coastguard Worker``` 477*89c4ff92SAndroid Build Coastguard WorkerThe input binding information contains all the essential information about the input. It is a tuple consisting of 478*89c4ff92SAndroid Build Coastguard Workerinteger identifiers for bindable layers (inputs, outputs) and the tensor info (data type, quantization information, 479*89c4ff92SAndroid Build Coastguard Workernumber of dimensions, total number of elements). 480*89c4ff92SAndroid Build Coastguard Worker 481*89c4ff92SAndroid Build Coastguard WorkerSimilarly, we can get the output binding information for an output layer by using the parser to retrieve output 482*89c4ff92SAndroid Build Coastguard Workertensor names and calling `GetNetworkOutputBindingInfo()`. 483*89c4ff92SAndroid Build Coastguard Worker 484*89c4ff92SAndroid Build Coastguard Worker#### Creating a Network using Tflite and Arm NN delegate file 485*89c4ff92SAndroid Build Coastguard Worker 486*89c4ff92SAndroid Build Coastguard WorkerAll operations with Tflite and networks are encapsulated in [`ArmnnNetworkExecutor`](./include/delegate/ArmnnNetworkExecutor.hpp) 487*89c4ff92SAndroid Build Coastguard Workerclass. 488*89c4ff92SAndroid Build Coastguard Worker 489*89c4ff92SAndroid Build Coastguard Worker##### Building a Model and creating Interpreter 490*89c4ff92SAndroid Build Coastguard WorkerThe first step with Tflite is to build a model from file by using Flatbuffer model class. 491*89c4ff92SAndroid Build Coastguard Workerwith that model we create the Tflite Interpreter. 492*89c4ff92SAndroid Build Coastguard Worker```c++ 493*89c4ff92SAndroid Build Coastguard Worker#include <tensorflow/lite/interpreter.h> 494*89c4ff92SAndroid Build Coastguard Worker 495*89c4ff92SAndroid Build Coastguard WorkerarmnnTfLiteParser::ITfLiteParserPtr parser = armnnTfLiteParser::ITfLiteParser::Create();m_model = tflite::FlatBufferModel::BuildFromFile(modelPath.c_str()); 496*89c4ff92SAndroid Build Coastguard Workertflite::ops::builtin::BuiltinOpResolver resolver; 497*89c4ff92SAndroid Build Coastguard Workertflite::InterpreterBuilder(*m_model, resolver)(&m_interpreter); 498*89c4ff92SAndroid Build Coastguard Worker``` 499*89c4ff92SAndroid Build Coastguard Workerafter the Interpreter is created we allocate tensors using the AllocateTensors function of the Interpreter 500*89c4ff92SAndroid Build Coastguard Worker```c++ 501*89c4ff92SAndroid Build Coastguard Workerm_interpreter->AllocateTensors(); 502*89c4ff92SAndroid Build Coastguard Worker``` 503*89c4ff92SAndroid Build Coastguard Worker 504*89c4ff92SAndroid Build Coastguard Worker##### Creating Arm NN Delegate file 505*89c4ff92SAndroid Build Coastguard WorkerArm NN Delegate file is created using the ArmnnDelegate constructor 506*89c4ff92SAndroid Build Coastguard WorkerThe constructor accepts a DelegateOptions object that is created from the 507*89c4ff92SAndroid Build Coastguard Workerlist of the preferred backends that we want to use, and the optimizerOptions object (optional). 508*89c4ff92SAndroid Build Coastguard WorkerIn this example we enable fast math and reduce all float32 operators to float16 optimizations. 509*89c4ff92SAndroid Build Coastguard WorkerThese optimizations can sometime improve the performance but can also cause degredation, 510*89c4ff92SAndroid Build Coastguard Workerdepending on the model and the backends involved, therefore one should try it out and 511*89c4ff92SAndroid Build Coastguard Workerdecide whether to use it or not. 512*89c4ff92SAndroid Build Coastguard Worker 513*89c4ff92SAndroid Build Coastguard Worker 514*89c4ff92SAndroid Build Coastguard Worker```c++ 515*89c4ff92SAndroid Build Coastguard Worker#include <armnn_delegate.hpp> 516*89c4ff92SAndroid Build Coastguard Worker#include <DelegateOptions.hpp> 517*89c4ff92SAndroid Build Coastguard Worker#include <DelegateUtils.hpp> 518*89c4ff92SAndroid Build Coastguard Worker 519*89c4ff92SAndroid Build Coastguard Worker/* enable fast math optimization */ 520*89c4ff92SAndroid Build Coastguard Workerarmnn::BackendOptions modelOptionGpu("GpuAcc", {{"FastMathEnabled", true}}); 521*89c4ff92SAndroid Build Coastguard WorkeroptimizerOptions.m_ModelOptions.push_back(modelOptionGpu); 522*89c4ff92SAndroid Build Coastguard Worker 523*89c4ff92SAndroid Build Coastguard Workerarmnn::BackendOptions modelOptionCpu("CpuAcc", {{"FastMathEnabled", true}}); 524*89c4ff92SAndroid Build Coastguard WorkeroptimizerOptions.m_ModelOptions.push_back(modelOptionCpu); 525*89c4ff92SAndroid Build Coastguard Worker/* enable reduce float32 to float16 optimization */ 526*89c4ff92SAndroid Build Coastguard WorkeroptimizerOptions.m_ReduceFp32ToFp16 = true; 527*89c4ff92SAndroid Build Coastguard Worker 528*89c4ff92SAndroid Build Coastguard WorkerarmnnDelegate::DelegateOptions delegateOptions(preferredBackends, optimizerOptions); 529*89c4ff92SAndroid Build Coastguard Worker/* create delegate object */ 530*89c4ff92SAndroid Build Coastguard Workerstd::unique_ptr<TfLiteDelegate, decltype(&armnnDelegate::TfLiteArmnnDelegateDelete)> 531*89c4ff92SAndroid Build Coastguard Worker theArmnnDelegate(armnnDelegate::TfLiteArmnnDelegateCreate(delegateOptions), 532*89c4ff92SAndroid Build Coastguard Worker armnnDelegate::TfLiteArmnnDelegateDelete); 533*89c4ff92SAndroid Build Coastguard Worker``` 534*89c4ff92SAndroid Build Coastguard Worker##### Registering the Arm NN delegate file to the Interpreter 535*89c4ff92SAndroid Build Coastguard WorkerRegistering the Arm NN delegate file will provide the TensorFlow Lite interpreter with an alternative implementation 536*89c4ff92SAndroid Build Coastguard Workerof the operators that can be accelerated by the Arm hardware 537*89c4ff92SAndroid Build Coastguard WorkerFor example: 538*89c4ff92SAndroid Build Coastguard Worker```c++ 539*89c4ff92SAndroid Build Coastguard Worker /* Register the delegate file */ 540*89c4ff92SAndroid Build Coastguard Worker m_interpreter->ModifyGraphWithDelegate(std::move(theArmnnDelegate)); 541*89c4ff92SAndroid Build Coastguard Worker``` 542*89c4ff92SAndroid Build Coastguard Worker### Object detection pipeline 543*89c4ff92SAndroid Build Coastguard Worker 544*89c4ff92SAndroid Build Coastguard WorkerGeneric object detection pipeline has 3 steps, to perform data pre-processing, run inference and decode inference results 545*89c4ff92SAndroid Build Coastguard Workerin the post-processing step. 546*89c4ff92SAndroid Build Coastguard Worker 547*89c4ff92SAndroid Build Coastguard WorkerSee [`ObjDetectionPipeline`](include/ObjectDetectionPipeline.hpp) and implementations for [`MobileNetSSDv1`](include/ObjectDetectionPipeline.hpp) 548*89c4ff92SAndroid Build Coastguard Workerand [`YoloV3Tiny`](include/ObjectDetectionPipeline.hpp) for more details. 549*89c4ff92SAndroid Build Coastguard Worker 550*89c4ff92SAndroid Build Coastguard Worker#### Pre-processing the Captured Frame 551*89c4ff92SAndroid Build Coastguard WorkerEach frame captured from source is read as an `cv::Mat` in BGR format but channels are swapped to RGB in a frame reader 552*89c4ff92SAndroid Build Coastguard Workercode. 553*89c4ff92SAndroid Build Coastguard Worker 554*89c4ff92SAndroid Build Coastguard Worker```c++ 555*89c4ff92SAndroid Build Coastguard Workercv::Mat processed; 556*89c4ff92SAndroid Build Coastguard Worker... 557*89c4ff92SAndroid Build Coastguard WorkerobjectDetectionPipeline->PreProcessing(frame, processed); 558*89c4ff92SAndroid Build Coastguard Worker``` 559*89c4ff92SAndroid Build Coastguard Worker 560*89c4ff92SAndroid Build Coastguard WorkerA pre-processing step consists of resizing the frame to the required resolution, padding and doing data type conversion 561*89c4ff92SAndroid Build Coastguard Workerto match the model input layer. 562*89c4ff92SAndroid Build Coastguard WorkerFor example, SSD MobileNet V1 that is used in our example takes for input a tensor with shape `[1, 300, 300, 3]` and 563*89c4ff92SAndroid Build Coastguard Workerdata type `uint8`. 564*89c4ff92SAndroid Build Coastguard Worker 565*89c4ff92SAndroid Build Coastguard WorkerPre-processing step returns `cv::Mat` object containing data ready for inference. 566*89c4ff92SAndroid Build Coastguard Worker 567*89c4ff92SAndroid Build Coastguard Worker#### Executing Inference 568*89c4ff92SAndroid Build Coastguard Worker```c++ 569*89c4ff92SAndroid Build Coastguard Workerod::InferenceResults results; 570*89c4ff92SAndroid Build Coastguard Worker... 571*89c4ff92SAndroid Build Coastguard WorkerobjectDetectionPipeline->Inference(processed, results); 572*89c4ff92SAndroid Build Coastguard Worker``` 573*89c4ff92SAndroid Build Coastguard WorkerInference step will call `ArmnnNetworkExecutor::Run` method that will prepare input tensors and execute inference. 574*89c4ff92SAndroid Build Coastguard WorkerWe have two separate implementations of the `ArmnnNetworkExecutor` class and its functions including `ArmnnNetworkExecutor::Run` 575*89c4ff92SAndroid Build Coastguard WorkerThe first Implementation [`ArmnnNetworkExecutor`](./common/include/ArmnnUtils/ArmnnNetworkExecutor.hpp)is utilizing 576*89c4ff92SAndroid Build Coastguard WorkerArm NN C++ API, 577*89c4ff92SAndroid Build Coastguard Workerwhile the second implementation [`ArmnnNetworkExecutor`](./include/delegate/ArmnnNetworkExecutor.hpp) is utilizing 578*89c4ff92SAndroid Build Coastguard WorkerTensorflow lite and its Delegate file mechanism. 579*89c4ff92SAndroid Build Coastguard Worker 580*89c4ff92SAndroid Build Coastguard Worker##### Executing Inference utilizing the Arm NN C++ API 581*89c4ff92SAndroid Build Coastguard WorkerA compute device performs inference for the loaded network using the `EnqueueWorkload()` function of the runtime context. 582*89c4ff92SAndroid Build Coastguard WorkerFor example: 583*89c4ff92SAndroid Build Coastguard Worker```c++ 584*89c4ff92SAndroid Build Coastguard Worker//const void* inputData = ...; 585*89c4ff92SAndroid Build Coastguard Worker//outputTensors were pre-allocated before 586*89c4ff92SAndroid Build Coastguard Worker 587*89c4ff92SAndroid Build Coastguard Workerarmnn::InputTensors inputTensors = {{ inputBindingInfo.first,armnn::ConstTensor(inputBindingInfo.second, inputData)}}; 588*89c4ff92SAndroid Build Coastguard Workerruntime->EnqueueWorkload(0, inputTensors, outputTensors); 589*89c4ff92SAndroid Build Coastguard Worker``` 590*89c4ff92SAndroid Build Coastguard WorkerWe allocate memory for output data once and map it to output tensor objects. After successful inference, we read data 591*89c4ff92SAndroid Build Coastguard Workerfrom the pre-allocated output data buffer. 592*89c4ff92SAndroid Build Coastguard WorkerSee [`ArmnnNetworkExecutor::ArmnnNetworkExecutor`](./common/include/ArmnnUtils/ArmnnNetworkExecutor.hpp) 593*89c4ff92SAndroid Build Coastguard Workerand [`ArmnnNetworkExecutor::Run`](./common/include/ArmnnUtils/ArmnnNetworkExecutor.hpp) for more details. 594*89c4ff92SAndroid Build Coastguard Worker 595*89c4ff92SAndroid Build Coastguard Worker##### Executing Inference utilizing the Tensorflow lite and Arm NN delegate file 596*89c4ff92SAndroid Build Coastguard WorkerInside the `PrepareTensors(..)` function, the input frame is copied to the Tflite Interpreter input tensor, 597*89c4ff92SAndroid Build Coastguard Workerthan the Tflite Interpreter performs inference for the loaded network using the `Invoke()` function. 598*89c4ff92SAndroid Build Coastguard WorkerFor example: 599*89c4ff92SAndroid Build Coastguard Worker```c++ 600*89c4ff92SAndroid Build Coastguard WorkerPrepareTensors(inputData, dataBytes); 601*89c4ff92SAndroid Build Coastguard Worker 602*89c4ff92SAndroid Build Coastguard Workerif (m_interpreter->Invoke() == kTfLiteOk) 603*89c4ff92SAndroid Build Coastguard Worker``` 604*89c4ff92SAndroid Build Coastguard WorkerAfter successful inference, we read data from the Tflite Interpreter output tensor and copy 605*89c4ff92SAndroid Build Coastguard Workerit to the outResults vector. 606*89c4ff92SAndroid Build Coastguard WorkerSee [`ArmnnNetworkExecutor::Run`](./include/delegate/ArmnnNetworkExecutor.hpp) for more details. 607*89c4ff92SAndroid Build Coastguard Worker 608*89c4ff92SAndroid Build Coastguard Worker#### Postprocessing 609*89c4ff92SAndroid Build Coastguard Worker 610*89c4ff92SAndroid Build Coastguard Worker##### Decoding and Processing Inference Output 611*89c4ff92SAndroid Build Coastguard WorkerThe output from inference must be decoded to obtain information about detected objects in the frame. In the examples 612*89c4ff92SAndroid Build Coastguard Workerthere are implementations for two networks but you may also implement your own network decoding solution here. 613*89c4ff92SAndroid Build Coastguard Worker 614*89c4ff92SAndroid Build Coastguard WorkerFor SSD MobileNet V1 models, we decode the results to obtain the bounding box positions, classification index, 615*89c4ff92SAndroid Build Coastguard Workerconfidence and number of detections in the input frame. 616*89c4ff92SAndroid Build Coastguard WorkerSee [`SSDResultDecoder`](./include/SSDResultDecoder.hpp) for more details. 617*89c4ff92SAndroid Build Coastguard Worker 618*89c4ff92SAndroid Build Coastguard WorkerFor YOLO V3 Tiny models, we decode the output and perform non-maximum suppression to filter out any weak detections 619*89c4ff92SAndroid Build Coastguard Workerbelow a confidence threshold and any redundant bounding boxes above an intersection-over-union threshold. 620*89c4ff92SAndroid Build Coastguard WorkerSee [`YoloResultDecoder`](./include/YoloResultDecoder.hpp) for more details. 621*89c4ff92SAndroid Build Coastguard Worker 622*89c4ff92SAndroid Build Coastguard WorkerIt is encouraged to experiment with threshold values for confidence and intersection-over-union (IoU) 623*89c4ff92SAndroid Build Coastguard Workerto achieve the best visual results. 624*89c4ff92SAndroid Build Coastguard Worker 625*89c4ff92SAndroid Build Coastguard WorkerThe detection results are always returned as a vector of [`DetectedObject`](./include/DetectedObject.hpp), 626*89c4ff92SAndroid Build Coastguard Workerwith the box positions list containing bounding box coordinates in the form `[x_min, y_min, x_max, y_max]`. 627*89c4ff92SAndroid Build Coastguard Worker 628*89c4ff92SAndroid Build Coastguard Worker#### Drawing Bounding Boxes 629*89c4ff92SAndroid Build Coastguard WorkerPost-processing step accepts a callback function to be invoked when the decoding is finished. We will use it 630*89c4ff92SAndroid Build Coastguard Workerto draw detections on the initial frame. 631*89c4ff92SAndroid Build Coastguard WorkerWith the obtained detections and using [`AddInferenceOutputToFrame`](./src/ImageUtils.cpp) function, we are able to draw bounding boxes around 632*89c4ff92SAndroid Build Coastguard Workerdetected objects and add the associated label and confidence score. 633*89c4ff92SAndroid Build Coastguard Worker```c++ 634*89c4ff92SAndroid Build Coastguard Worker//results - inference output 635*89c4ff92SAndroid Build Coastguard WorkerobjectDetectionPipeline->PostProcessing(results, [&frame, &labels](od::DetectedObjects detects) -> void { 636*89c4ff92SAndroid Build Coastguard Worker AddInferenceOutputToFrame(detects, *frame, labels); 637*89c4ff92SAndroid Build Coastguard Worker }); 638*89c4ff92SAndroid Build Coastguard Worker``` 639*89c4ff92SAndroid Build Coastguard WorkerThe processed frames are written to a file or displayed in a separate window. 640