将Darkflow转换的YOLO模型移植到TensorFlow安卓相机检测Demo
把自定义YOLO模型移植到TensorFlow Android Camera Detection Demo的步骤
我来一步步帮你搞定这个移植,都是实际操作过的经验,跟着来就行:
1. 准备好Android端需要的文件
首先把你用darkflow生成的license.pb文件,还有自己整理的标签文件(比如labels.txt,每行写一个检测类别,比如你的车牌检测就写license_plate),一起放到Android Demo项目的app/src/main/assets目录里。如果assets目录不存在,自己新建一个就行。
2. 替换Demo里的模型配置
打开Demo里的核心检测类(一般是DetectorActivity.java或者类似的文件),找到原来的模型和标签路径配置,替换成你自己的:
// 替换成你的模型和标签路径 private static final String MODEL_FILE = "file:///android_assets/license.pb"; private static final String LABEL_FILE = "file:///android_assets/labels.txt"; // 替换成你YOLO模型训练时的输入尺寸,比如416x416 private static final int INPUT_SIZE = 416;
3. 修改模型输出节点配置
YOLO的输出节点和Demo默认的SSD不一样,你之前用Python分析pb文件的时候,应该已经找到输出层的名字了(比如通常是output或者yolo-v3/output这类),把它加到代码里:
// 替换成你实际的输出节点名称 private static final String OUTPUT_TENSOR_NAME = "output";
然后找到原来获取输出张量的代码,把默认的输出节点换成你这个,比如原来的getTensor("detection_scores")这类,改成获取你指定的输出张量。
4. 重写YOLO输出解析逻辑
这一步是关键,因为YOLO的输出格式和SSD完全不同,你需要把模型输出的张量转换成Android端能显示的检测框和标签。大致的逻辑是这样:
- YOLO的输出张量形状一般是
[1, num_boxes, 5 + num_classes],其中前5个值是x, y, w, h, confidence(相对坐标和置信度),后面是每个类别的概率 - 遍历每个检测框,先过滤掉置信度低于阈值(比如0.5)的框
- 找到当前框概率最高的类别,对应到你的标签文件
- 把相对坐标转换成图像的绝对坐标(因为摄像头采集的图像尺寸和模型输入尺寸可能不一样,要做比例换算)
给你一段参考代码片段:
// 获取输出张量 float[] outputs = outputTensor.copyAsFloatArray(); // 假设输出形状是[1, 10647, 6](比如YOLOv3 tiny的输出) int numBoxes = outputs.length / (5 + numClasses); for (int i = 0; i < numBoxes; i++) { int baseIndex = i * (5 + numClasses); float confidence = outputs[baseIndex + 4]; // 过滤低置信度的框 if (confidence < 0.5) continue; // 找到概率最高的类别 float maxProb = 0; int classIndex = -1; for (int j = 0; j < numClasses; j++) { float prob = outputs[baseIndex + 5 + j]; if (prob > maxProb) { maxProb = prob; classIndex = j; } } if (classIndex == -1) continue; // 转换坐标:YOLO输出的是相对中心x、y,宽高w、h,要转成左上角和右下角绝对坐标 float relX = outputs[baseIndex]; float relY = outputs[baseIndex + 1]; float relW = outputs[baseIndex + 2]; float relH = outputs[baseIndex + 3]; // 根据图像实际尺寸计算绝对坐标 int imgWidth = bitmap.getWidth(); int imgHeight = bitmap.getHeight(); int left = (int) ((relX - relW / 2) * imgWidth); int top = (int) ((relY - relH / 2) * imgHeight); int right = (int) ((relX + relW / 2) * imgWidth); int bottom = (int) ((relY + relH / 2) * imgHeight); // 把这个检测框和标签存起来,后面用来绘制 detections.add(new Detection(labelList.get(classIndex), confidence, left, top, right, bottom)); }
5. 调整图像预处理逻辑
YOLO对输入图像的预处理有要求,要和你训练时一致:
- 把摄像头采集到的图像缩放到你设置的
INPUT_SIZE(比如416x416) - 注意颜色空间:如果训练时用的是BGR,要把Android的RGB图像转换成BGR;如果是RGB就不用改
- 有些YOLO模型需要对像素值做归一化(比如除以255),这部分也要和训练时对齐
6. 测试和调试
把项目编译安装到Android设备上,测试检测效果:
- 如果检测不到,先检查模型路径、标签文件是否正确,输出节点名称有没有写错
- 调整置信度阈值,比如从0.5降到0.3试试
- 确认输入尺寸和训练时完全一致,差一点都可能出问题
内容的提问来源于stack exchange,提问作者Santle Camilus
相关产品推荐
相关产品推荐

