如何将Jupyter训练的YOLOv3自定义模型集成到Kotlin安卓应用
Kotlin安卓端接入自定义YOLOv3实时目标检测实现步骤
核心思路是先把你手上Darknet格式的YOLOv3模型转成安卓端可硬件加速的TFLite格式,再对接摄像头流做推理,最后绑定你已有的页面跳转逻辑,全程不需要改你原来模型训练的部分,和你Jupyter里的检测逻辑完全对齐。
1. PC端完成模型格式转换
你现有的yolov3_custom.cfg、yolov3_custom.weights是Darknet原生格式,安卓端直接调用兼容性差、速度慢,先转成TFLite格式:
- 先在PC端Python环境装依赖:
pip install tensorflow==2.15.0 opencv-python numpy - 用TensorFlow官方提供的Darknet模型转换脚本,先将cfg和weights导出为SavedModel格式,转换前一定要核对参数:类别数、锚点值必须和你自定义训练时的配置完全一致,每个检测头的filters值要按
(类别数+5)*3计算修改,别直接用默认COCO数据集的80类配置,不然推理结果完全错误。 - 将导出的SavedModel转为动态量化的TFLite格式,量化后模型体积能压缩到原大小的1/4,安卓端推理速度能提升3倍以上,最终得到
yolov3_custom.tflite文件。另外单独存一个标签文件labels.txt,每行写一个你自定义的类别名。
2. 安卓项目依赖配置
打开你已经完成基础页面开发的Kotlin项目,修改配置:
- 在app模块的
build.gradle依赖块中添加所需库:
dependencies { // OpenCV安卓版,用于处理帧格式、绘制检测边界框 implementation 'org.opencv:opencv-android:4.8.0' // TFLite核心库,用于加载模型、执行推理 implementation 'org.tensorflow:tensorflow-lite:2.15.0' implementation 'org.tensorflow:tensorflow-lite-support:0.4.4' // CameraX库,用于稳定调用设备摄像头,适配不同安卓版本 implementation 'androidx.camera:camera-core:1.3.0' implementation 'androidx.camera:camera-camera2:1.3.0' implementation 'androidx.camera:camera-lifecycle:1.3.0' implementation 'androidx.camera:camera-view:1.3.0' }
- 在同文件的android.defaultConfig块中添加NDK架构过滤,只适配主流手机架构,减小安装包体积:
ndk { abiFilters 'armeabi-v7a', 'arm64-v8a' }
- 在项目
app/src/main路径下新建assets文件夹,把转好的yolov3_custom.tflite和labels.txt放进去。
3. 实时检测逻辑开发
这部分逻辑和你Jupyter里的流程基本一致,只是把PC端摄像头调用换成安卓端的CameraX:
- 封装一个检测辅助类,统一处理模型加载、帧预处理、推理、后处理、绘制边界框逻辑:
- 模型加载:从assets目录读取tflite文件生成内存映射,实例化TFLite解释器,开启NNAPI硬件加速,大部分安卓机型都能支持,推理速度会快很多。
- 帧预处理:将CameraX返回的YUV格式摄像头帧转为OpenCV的Mat对象,再转成RGB格式,resize到你模型训练时的输入尺寸(常用416416/608608),将像素值归一化到0-1区间,整理成模型要求的输入张量格式。
- 推理:把预处理好的输入张量传入解释器,拿到三个检测头的输出结果。
- 后处理:和你Jupyter里写的逻辑完全一致,先做置信度阈值过滤,再做NMS非极大值抑制,最终得到有效检测框的坐标、置信度、类别ID。
- 绘制结果:把检测框坐标映射回原始摄像头帧的尺寸,用OpenCV的
rectangle、putText方法把边界框、类别名、置信度绘制到帧上。
- 在启动页的布局中添加PreviewView控件用来显示摄像头画面,绑定CameraX生命周期,每获取到一帧就传入检测辅助类处理,把绘制完检测结果的帧转为Bitmap显示在PreviewView上,就实现了和PC端一致的实时检测效果。
- 记得在Activity中动态申请摄像头权限,用户授权通过后再启动摄像头采集。
4. 对接页面跳转逻辑
你已经完成了其他Activity的基础开发,这部分对接很简单:
- 在检测页面的布局中放置你已经设计好的“下一步”按钮。
- 给按钮添加点击监听,点击时可以根据需求把当前检测结果(比如识别到的类别、当前检测帧截图)通过Intent传递给下一个Activity,调用
startActivity()完成跳转即可。跳转前记得停止摄像头帧采集、释放TFLite解释器资源,避免内存泄漏。
踩坑提示:不要直接用OpenCV DNN模块加载原生.weights文件在安卓端跑,没有硬件加速的情况下中低端机型帧率通常只有3-5帧,体验很差,用量化后的TFLite模型帧率基本能稳定在20fps以上。如果转换Darknet模型觉得麻烦,也可以先把cfg和weights转成ONNX格式,再从ONNX转TFLite,只要参数匹配推理效果完全一致。
内容的提问来源于stack exchange,提问作者Padala Kavya
相关产品推荐
相关产品推荐

