Advertisement

How to Implement Object Detection with YOLO v3 on Mobil

阅读量:

作者:禅与计算机程序设计艺术

1.简介

随着移动设备硬件性能持续提升,在物证检测技术方面也取得了长足进步,在智能终端领域已获得广泛应用

2.相关知识

2.1. 物体检测

物体检测(Object detection) is a crucial task in the field of computer vision. It has significant applications across various fields, including security, face recognition, and natural language processing. Its primary function is to identify objects of interest within images or video streams and provide their location, size, and category information.

图1: 物体检测的流程图。

通常情况下,在计算机视觉领域中将物体检测划分为两个主要阶段:第一阶段是特征提取过程,在这一阶段系统会从输入图片中提取相应的图像区域特征;第二阶段则是分类器训练过程,在这一过程中系统利用这些特征来训练一个分类器模型,并最终实现对未知图像中物体的识别。一般而言,在实际应用中一个完整的物体检测系统通常包含三个主要组件:

  1. 物体识别模块(Detection module)。
  2. 被提取特征的模块(Feature extraction module)。
  3. 被分类决策的单元(Classifier decision unit)

2.2. 相关术语

  • 图像与视频物体检测任务 是计算机视觉领域的重要研究方向之一。
  • 目标定位机制(Detector)是该领域中的核心算法之一,在图像与视频中实现精准的目标识别。
  • 在目标定位过程中,目标定位框(Bounding box) 是用于界定待识别对象区域的关键参数。
  • 为了衡量定位结果的可靠性程度,在实际应用中通常引入了**检测准确性(Confidence)**这一量化指标。
  • 在分类属性(Class)的基础上进一步细化分析,在复杂场景下可实现多维度特征信息的有效提取与整合。

2.3. 物体检测方法

当前物体检测的主要技术可分为两类:主要采用传统算法与深度学习实现的全连接算法模型

2.3.1. 传统算法

传统的物体检测方法包括传统的滑动窗口法、Haar特征法、K-近邻法等。

2.3.1.1. 滑动窗口法

滑动窗口技术是一种高效可靠的物体检测方案。该方法的核心在于扫描图像中的目标区域,并通过分析其边缘特征、角度和尺寸来识别目标物体。尽管该方法在检测精度上表现优异,但其计算复杂度较高,在实际应用中往往会导致运行时间显著延长。

2.3.1.2. Haar特征法

该算法主要依赖于线性加权组合的 Haar 特征。通过构造一系列正方形窗口并在图像中滑动来提取单像素级别的 Haar 特征。随后通过将这些 Haar 特征与相应模板进行匹配分析来推导出物体的位置、尺寸以及旋转角度参数。由于计算过程涉及大量数据处理和冗余操作, 该算法的时间复杂度相对较高。

2.3.1.3. K-近邻法

该算法属于非监督式机器学习体系中的基础模型之一,在解决分类任务方面表现出色。其核心思路在于通过计算样本间的相似程度来推断类别归属关系,并选取与目标样本距离最近的前k个训练样本作为参考依据。尽管该方法依赖于海量数据进行建模运算,在实际应用中无需传统意义上的模型训练步骤即可完成预测任务。然而由于该方法对训练数据量敏感,在处理复杂场景时往往难以达到深度学习算法所具有的高度准确性

2.3.2. 深度学习方法

深度学习体系涵盖多种重要的神经网络结构,其中最为常见的是卷积神经网元结构(CNN)、循环神经网元结构(RNN)及其衍生形式等

2.3.2.1. CNN

其主要工作流程是通过执行卷积操作来生成多个具有特定特性的特征图。随后会对这些特征图执行下采样处理以缩小尺寸并减少计算负担。最后通过全连接层完成分类任务并输出相应的预测结果。

2.3.2.2. RNN

循环神经网络(Recurrent Neural Network, RNN),是一种核心技术手段,在时间序列数据分析中表现出色。该技术通过引入隐层状态变量来捕捉序列信息,并能有效预测后续行为。RNNs具备自主识别长程依存关系的能力,并通过采样和平滑处理输入数据来有效地抑制噪声干扰。

2.3.2.3. YOLO v3

YOLO (You Only Look Once) v3 目前是物体检测领域的流行代表作之一。该算法的核心理念是基于单次回归实现目标检测。其主要架构包含两个关键组件:一个用于提取图像空间特征的卷积神经网络(CNN),以及一个用于恢复丢失空间信息的上采样层。具体流程如下:将输入图像送入卷积神经网络进行前向传播,在此过程中CNN会提取出图像的空间特征并生成初步的候选边界框预测(bounding boxes)。随后利用定位网络进一步优化边界框位置及置信度评估,并结合分类网络识别目标类别及其对应概率值。最后通过NMS(Non-Maximum Suppression)技术对多个边界框进行抑制处理以去除冗余候选框,从而获得最终可靠的检测结果。

3. Core Algorithm and Operations Steps

3.1. Architecture Design of the Model

YOLO v3采用了基于Darknet-53的设计方案。针对移动端需求,该算法优化了架构以提升效率。如图所示

图2: YOLO v3网络结构图

YOLO v3 的网络由五个主要模块构成:

  1. Darknet-53 模块: 在基础 Darknet-53 模块的基础上, 去除了残差连接, 提高了卷积核的间距以降低模型复杂度.
  2. YOLO 分支: YOLO 分支由两个卷积层和两个输出层构成, 其中第一个卷积层用于提取图像信息, 第二个卷积层用于生成预测结果. 输出层中的第一个输出用于计算 bounding box 中心坐标的损失, 第二个输出则用于计算 bounding box 尺寸及其置信度的损失.
  3. 损失函数: 通过将预测值与 ground truth 结合, 分别计算 bounding box 置信度的损失、坐标偏移量的损失以及类别标签的交叉熵损失, 实现三者的目标函数进行联合优化.
  4. 数据扩增: 采用多尺度预测策略, 减弱模型对输入图像尺寸高度敏感的问题.
  5. 非极大值抑制 (NMS): 对于置信度较高的 bounding box 进行筛选, 去除冗余检测结果以提高检测精度.

3.2. Implementation of the Model in TensorFlow Lite

为了使YOLO v3模型在移动设备上实现实时运行, 该系统运用了基于TensorFlow Lite的高效计算引擎。其支持针对不同硬件架构的优化编译方案, 其中包含ARM NEON指令集和x86 SIMD指令集。

3.2.1. Build Script for Android Platform

我们可以使用以下脚本编译 YOLO v3 模型的 Android 版本:

复制代码
    #!/bin/bash
    
    # Install required packages
    sudo apt update && sudo apt install -y \
    autoconf automake libtool curl make g++ unzip zip sqlite3 libc6-dev zlib1g-dev
    
    # Clone darknet repo
    git clone https://github.com/AlexeyAB/darknet
    
    # Enter darknet directory
    cd darknet
    
    # Compile dependencies
    make -j$(nproc)
    
    # Download weight file
    wget https://pjreddie.com/media/files/yolov3.weights
    
    # Set up android toolchain and NDK path
    export ANDROID_HOME=$HOME/Android/Sdk
    export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:${ANDROID_HOME}/ndk-bundle
    
    # Set up build environment variables for cmake
    export CXX=aarch64-linux-android-g++
    export CC=aarch64-linux-android-gcc
    export CMAKE_TOOLCHAIN_FILE=${ANDROID_HOME}/ndk-bundle/build/cmake/android.toolchain.cmake
    export ABI=arm64-v8a
    
    # Create build directory
    mkdir build && cd build
    
    # Generate Makefiles for building arm64 library
    cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../jniLibs/..
    
    # Build shared object files for Android
    make -j$(nproc)
    
    # Build final AAR package
    cpack -G Android Gradle
    
    # Move built AAR package back to root folder
    mv./app/build/outputs/aar/*-debug.aar.
    
    # Exit from build script directory
    cd../../..
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

以上脚本配置了编译环境变量,并获取了YOLO v3模型的预训练权重文件。同时,请注意修改脚本中的ABI设置以适应您使用的CPU类型。

运行脚本 sh build_script.sh ,待编译完成时,在当前目录中将检测到 *-debug.aar 文件,即是编译好的 YOLO v3 模型的 AAR 包。

3.2.2. Convert Weights File to TF Lite Format

为了在Android平台上使用YOLO v3模型,我们需要将YOLO v3的预训练权重文件转换为可被TensorFlow Lite解析的格式,即通常以TFLite文件的形式存在。

复制代码
    import tensorflow as tf
    from absl import app, flags
    from absl.flags import FLAGS
    
    flags.DEFINE_string('input', None, 'Path to input weights file')
    flags.DEFINE_string('output', None, 'Path to output tflite model file')
    
    def main(_):
    
    # Load YOLO v3 architecture and load its pretrained weights
    yolo = tf.keras.models.load_model('/path/to/yolov3.h5', compile=False)
    
    # Define input and output shapes according to TensorFlow Lite requirements
    input_shape = (416, 416, 3)
    output_shapes = [(13, 13, 3, 85), (26, 26, 3, 85), (52, 52, 3, 85)]
    
    # Convert Keras model into a frozen graph
    converter = tf.lite.TFLiteConverter.from_keras_model(yolo)
    converter.optimizations = [tf.lite.Optimize.DEFAULT]
    converter.representative_dataset = representative_data_gen
    converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
    converter.inference_input_type = tf.int8
    converter.inference_output_type = tf.float32
    converter.experimental_new_converter = True
    
    # Fine tune TensorFlow Lite performance parameters for mobile devices
    converter.experimental_new_quantizer = False
    converter.target_spec.supported_types = [tf.uint8]
    converter.inference_input_type = tf.uint8
    converter.inference_output_type = tf.float32
    converter.allow_custom_ops = True
    converter.experimental_enable_resource_variables = True
    
    # Convert keras model into TFLite format
    tflite_model = converter.convert()
    
    # Save converted model to disk
    open(FLAGS.output, "wb").write(tflite_model)
    
    
    if __name__ == '__main__':
    try:
        app.run(main)
    except SystemExit:
        pass
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

在我们的脚本中,我们引入了 TensorFlow、absl 和 flags 模块。其中 flags 模块用于解析命令行参数。

在主函数 main() 中,我们导入了YOLOv3网络结构,并导入了预训练权重文件 /path/to/yolov3.h5

之后,我们定义了输入和输出形状,以符合 TensorFlow Lite 的需求。

接下来,我们将 Keras 模型转换成了一个冻结图(Frozen Graph)。

在设置 TensorFlow Lite 转换器参数的过程中,我们明确了优化策略,并明确了推理数据集路径及模型分辨率设置等关键细节。具体包括明确了量化策略的选择以及是否采用了新的量化方法等技术细节设置。此外还明确了推理任务类型设置(即模型处理何种类型的推理),以及是否支持自定义计算节点和是否允许使用资源型变量等参数配置项。

最后,我们将 Keras 模型转换为 TFLite 格式,并保存到磁盘上。

3.2.3. Integration With Android Studio Project

为实现Android Studio中TensorFlow Lite库的导入,以下是完成此操作的具体步骤:

  1. 创建新的 Android Studio 项目,并命名为 "YoloV3TF"。

  2. app/build.gradle 文件中添加以下依赖项:

复制代码
    implementation 'org.tensorflow:tensorflow-lite:+'

    implementation 'org.tensorflow:tensorflow-lite-gpu:+' // optional GPU acceleration if your device supports it
    implementation 'org.tensorflow:tensorflow-lite-support:+' // optional support libraries including optional TF Lite Task Library
    
         
         
    代码解读

在 MainActivity.java 或其他适当的位置初始化一个 TensorFlow Lite 对象,并在此对象中加载 TFLite 模型。

复制代码
    private static final String MODEL_PATH = "/path/to/yolov3.tflite";

    
    private Interpreter interpreter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    // Initialize TensorFlow Lite
            try {
                InputStream inputStream = getAssets().open(MODEL_PATH);
                byte[] model = new byte[inputStream.available()];
                inputStream.read(model);
                inputStream.close();
    
                ByteBuffer buffer = ByteBuffer.wrap(model);
                interpreter = new Interpreter(buffer);
    
            } catch (IOException e) {
                Log.d("TensorFlowLite", "Error reading model");
        }
    
    ...
    }
    
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
         
    代码解读

在本例中

此外, 您如果有本地存储的 TFLite 模型文件(如本地 SDCard), 您可以调用 File API 读取该文件, 并将其传递给 TensorFlow Lite 的构造函数

全部评论 (0)

还没有任何评论哟~