Android Studio中TFLite模型推理报Fatal signal 11错误的解决方法
解决YOLOv4 TFLite在Android上的SIGSEGV段错误
核心原因分析
Fatal signal 11 (SIGSEGV) 是内存访问越界错误,你的代码中主要存在输入输出尺寸不匹配、Bitmap缩放错误两个关键问题,同时可能伴随模型转换或Interpreter初始化的问题。
解决方案步骤
1. 修正输入Bitmap尺寸,避免像素读取越界
你的代码中没有将输入图像缩放到模型要求的416x416,导致getPixels读取超出Bitmap范围的像素,触发内存错误:
// 修改createBoundingBox方法中的resizedImage创建逻辑 public void createBoundingBox(Bitmap image){ // 强制将图像缩放到模型要求的416x416 Bitmap resizedImage = Bitmap.createScaledBitmap(image, 416, 416, true); try { MappedByteBuffer tfliteModel = loadModelFile(); TensorBuffer inputFeature0 = TensorBuffer.createFixedSize(new int[]{1, 416, 416, 3}, DataType.FLOAT32); ByteBuffer byteBuffer = convertBitmapToByteBuffer(resizedImage); inputFeature0.loadBuffer(byteBuffer); // 后续代码... } catch (IOException e) { e.printStackTrace(); } } // 同时修正convertBitmapToByteBuffer方法,固定输入尺寸为416 private ByteBuffer convertBitmapToByteBuffer(Bitmap bitmap){ final int INPUT_SIZE = 416; ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4 * INPUT_SIZE * INPUT_SIZE * 3); byteBuffer.order(ByteOrder.nativeOrder()); int[] intValues = new int[INPUT_SIZE * INPUT_SIZE]; // 确保读取的像素范围不超过Bitmap尺寸 bitmap.getPixels(intValues, 0, INPUT_SIZE, 0, 0, INPUT_SIZE, INPUT_SIZE); for (int i = 0; i < INPUT_SIZE; i++){ for(int j = 0; j < INPUT_SIZE; j++) { int val = intValues[i * INPUT_SIZE + j]; // 注意:部分YOLO模型要求输入为BGR格式,若推理结果异常可交换R和B的顺序 byteBuffer.putFloat(((val >> 16) & 0xFF) * (1.f / 255)); // R通道 byteBuffer.putFloat(((val >> 8) & 0xFF) * (1.f / 255)); // G通道 byteBuffer.putFloat((val & 0xFF) * (1.f / 255)); // B通道 } } return byteBuffer; }
2. 修正模型输出尺寸,匹配实际模型结构
YOLOv4 TFLite模型的输出不是[1,416,416,3],通常是3个不同尺度的检测张量(比如针对COCO 80类,形状为[1,13,13,255]、[1,26,26,255]、[1,52,52,255])。硬编码错误的输出尺寸会导致内存越界:
// 替换手动创建输出张量的逻辑,动态获取模型输出形状 Interpreter tflite = new Interpreter(tfliteModel); Object[] inputs = {inputFeature0.getBuffer()}; Map<Integer, Object> outputs = new HashMap<>(); // 遍历所有输出张量,动态创建对应尺寸的TensorBuffer int outputCount = tflite.getOutputTensorCount(); for (int i = 0; i < outputCount; i++) { Tensor outputTensor = tflite.getOutputTensor(i); int[] outputShape = outputTensor.shape(); TensorBuffer outputBuffer = TensorBuffer.createFixedSize(outputShape, outputTensor.dataType()); outputs.put(i, outputBuffer.getBuffer()); } // 执行推理 tflite.runForMultipleInputsOutputs(inputs, outputs); // 后续处理输出时,根据实际输出形状解析检测结果 // List<Detection> detections = processModelOutputs(outputs);
3. 重新生成ML Model Binding代码(若使用自动生成)
如果使用Android Studio的ML Model Binding插件,重新导入模型:
- 确保导入时选择正确的模型文件,插件会自动识别输入输出形状
- 若生成的代码仍报错,检查模型是否转换正确:在Python中用以下代码验证模型的输入输出:
import tensorflow as tf interpreter = tf.lite.Interpreter(model_path="yolov4.tflite") interpreter.allocate_tensors() input_details = interpreter.get_input_details() output_details = interpreter.get_output_details() print("输入形状:", input_details[0]['shape']) print("输出形状列表:", [d['shape'] for d in output_details])
将输出的形状对应到自动生成的代码中,确保没有不匹配的情况。
4. 优化Interpreter初始化配置
添加线程数和NNAPI设置,避免内存或性能问题:
// 创建Interpreter时添加配置选项 Interpreter.Options options = new Interpreter.Options(); options.setNumThreads(4); // 根据设备核心数调整 options.setUseNNAPI(true); // 启用硬件加速 Interpreter tflite = new Interpreter(tfliteModel, options);
内容的提问来源于stack exchange,提问作者Maël
相关产品推荐
相关产品推荐

