E/flutter(8115):[错误:flutter/runtime/dart_vm_initializer.cc(41)]

问题描述 投票:0回答:1

E / flutter(8115):[错误:flutter/runtime/dart_vm_initializer.cc(41)]未处理的异常:PlatformException(100,检测错误,java.lang.IllegalArgumentException:无法复制到TensorFlowLite张量(serving_default_images:0)来自 23040 字节的 Java 缓冲区的 4915200 字节。

我正在尝试使用 fluttervision 包将我的 yolov8 模型集成到 flutter 中。当我在 netron 应用程序中看到我的模型时,它显示我的输入图像应该是张量:float32[1,3,640,640] 所以我添加了一个函数将unit8转换为float32,但当我从图库中选择图像并尝试执行检测时,仍然会出现此错误。我在这里附上我的代码的代码片段,请帮助!!!

`code for object detection using camera`
     class YoloVideo extends StatefulWidget {
     final FlutterVision vision;
     const YoloVideo({Key? key, required this.vision}) : super(key: key);

     @override
     State<YoloVideo> createState() => _YoloVideoState();
     }

    class _YoloVideoState extends State<YoloVideo> {
    late CameraController controller;
    late List<Map<String, dynamic>> yoloResults;
    CameraImage? cameraImage;
    bool isLoaded = false;
    bool isDetecting = false;

    @override
    void initState() {
    super.initState();
    init();
    }

    init() async {
    cameras = await availableCameras();
    controller = CameraController(cameras[0], ResolutionPreset.medium);
    controller.initialize().then((value) {
      loadYoloModel().then((value) {
        setState(() {
          isLoaded = true;
          isDetecting = false;
          yoloResults = [];
        });
      });
      });
     }

    @override
    void dispose() async {
    super.dispose();
    controller.dispose();
    }

    @override
    Widget build(BuildContext context) {
    final Size size = MediaQuery.of(context).size;
    if (!isLoaded) {
      return const Scaffold(
        body: Center(
          child: Text("Model not loaded, waiting for it"),
        ),
      );
     }
    
      }

     // Example image preprocessing function
     Future<Uint8List> preprocessImage(File imageFile) async {
     final imageBytes = await imageFile.readAsBytes();
     final decodedImage = img.decodeImage(imageBytes);

     // Resize image to 640x640
     final resizedImage = img.copyResize(decodedImage!, width: 640, height: 640);

     // Convert to RGB format
     final pngBytes = img.encodePng(resizedImage!);

     // Normalize pixel values to [0, 1]
     final normalizedBytes = Float32List.fromList(pngBytes!.map((byte) => byte / 255.0).toList());

     // Expand dimensions to match [1, 3, 640, 640]
     final inputTensor = normalizedBytes.expand((value) => [value, value, value]).toList();
     final reshapedTensor = Float32List.fromList([1.0] + inputTensor);

     return Uint8List.fromList(reshapedTensor.map((value) => (value * 255).round()).toList());
     }


  Future<void> loadYoloModel() async {
    await widget.vision.loadYoloModel(
        labels: 'assets/task1.txt',
        modelPath: 'assets/task1.tflite',
        modelVersion: "yolov8",
        numThreads: 2,
        useGpu: true);
    setState(() {
      isLoaded = true;
    });
  }

  Future<void> yoloOnFrame(CameraImage cameraImage) async {
    final result = await widget.vision.yoloOnFrame(
        bytesList: cameraImage.planes.map((plane) => plane.bytes).toList(),
        imageHeight: cameraImage.height,
        imageWidth: cameraImage.width,
        iouThreshold: 0.4,
        confThreshold: 0.4,
        classThreshold: 0.5);
    if (result.isNotEmpty) {
      setState(() {
        yoloResults = result;
      });
    }
  }

  Future<void> startDetection() async {
    setState(() {
      isDetecting = true;
    });
    if (controller.value.isStreamingImages) {
      return;
    }
    await controller.startImageStream((image) async {
      if (isDetecting) {
        cameraImage = image;
        yoloOnFrame(image);
      }
    });
  }

  Future<void> stopDetection() async {
    setState(() {
      isDetecting = false;
      yoloResults.clear();
    });
  }

  List<Widget> displayBoxesAroundRecognizedObjects(Size screen) {
    if (yoloResults.isEmpty) return [];
    double factorX = screen.width / (cameraImage?.height ?? 1);
    double factorY = screen.height / (cameraImage?.width ?? 1);

    Color colorPick = const Color.fromARGB(255, 50, 233, 30);

    return yoloResults.map((result) {
      return Positioned(
        left: result["box"][0] * factorX,
        top: result["box"][1] * factorY,
        width: (result["box"][2] - result["box"][0]) * factorX,
        height: (result["box"][3] - result["box"][1]) * factorY,
        child: Container(
          decoration: BoxDecoration(
            borderRadius: const BorderRadius.all(Radius.circular(10.0)),
            border: Border.all(color: Colors.pink, width: 2.0),
          ),
          child: Text(
            "${result['tag']} ${(result['box'][4] * 100).toStringAsFixed(0)}%",
            style: TextStyle(
              background: Paint()..color = colorPick,
              color: Colors.white,
              fontSize: 18.0,
            ),
          ),
        ),
      );
    }).toList();
  }
}

`code for image deection from gallary`
class YoloImageV8 extends StatefulWidget {
  final FlutterVision vision;
  const YoloImageV8({Key? key, required this.vision}) : super(key: key);

  @override
  State<YoloImageV8> createState() => _YoloImageV8State();
}

class _YoloImageV8State extends State<YoloImageV8> {

  Future<Uint8List> preprocessImage(File imageFile) async {
    final imageBytes = await imageFile.readAsBytes();
    final decodedImage = img.decodeImage(imageBytes);

    // Resize image to 640x640
    final resizedImage = img.copyResize(decodedImage!, width: 640, height: 640);

    // Convert to RGB format
    final pngBytes = img.encodePng(resizedImage!);

    // Normalize pixel values to [0, 1]
    final normalizedBytes = Float32List.fromList(pngBytes!.map((byte) => byte / 255.0).toList());

    // Expand dimensions to match [1, 3, 640, 640]
    final inputTensor = normalizedBytes.expand((value) => [value, value, value]).toList();
    final reshapedTensor = Float32List.fromList([1.0] + inputTensor);

    return Uint8List.fromList(reshapedTensor.map((value) => (value * 255).round()).toList());
  }


  late List<Map<String, dynamic>> yoloResults;
  File? imageFile;
  int imageHeight = 1;
  int imageWidth = 1;
  bool isLoaded = false;

  @override
  void initState() {
    super.initState();
    loadYoloModel().then((value) {
      setState(() {
        yoloResults = [];
        isLoaded = true;
      });
    });
  }

  @override
  void dispose() async {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final Size size = MediaQuery.of(context).size;
    if (!isLoaded) {
      return const Scaffold(
        body: Center(
          child: Text("Model not loaded, waiting for it"),
        ),
      );
    }
    return Stack(
      fit: StackFit.expand,
      children: [
        imageFile != null ? Image.file(imageFile!) : const SizedBox(),
        Align(
          alignment: Alignment.bottomCenter,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              TextButton(
                onPressed: pickImage,
                child: const Text("Pick an image"),
              ),
              ElevatedButton(
                onPressed: yoloOnImage,
                child: const Text("Detect"),
              )
            ],
          ),
        ),
        ...displayBoxesAroundRecognizedObjects(size),
      ],
    );
  }

  Future<void> loadYoloModel() async {
    await widget.vision.loadYoloModel(
        labels: 'assets/task1.txt',
        modelPath: 'assets/task1.tflite',
        modelVersion: "yolov8",
        quantization: false,
        numThreads: 2,
        useGpu: true);
    setState(() {
      isLoaded = true;
    });
  }

  Future<void> pickImage() async {
    final ImagePicker picker = ImagePicker();
    // Capture a photo
    final XFile? photo = await picker.pickImage(source: ImageSource.gallery);
    if (photo != null) {
      setState(() {
        imageFile = File(photo.path);
      });
    }
  }

  yoloOnImage() async {
    yoloResults.clear();
    Uint8List byte = await imageFile!.readAsBytes();
    final image = await decodeImageFromList(byte);
    imageHeight = image.height;
    imageWidth = image.width;
    final result = await widget.vision.yoloOnImage(
        bytesList: byte,
        imageHeight: image.height,
        imageWidth: image.width,
        iouThreshold: 0.8,
        confThreshold: 0.4,
        classThreshold: 0.5);
    if (result.isNotEmpty) {
      setState(() {
        yoloResults = result;
      });
    }
  }

  List<Widget> displayBoxesAroundRecognizedObjects(Size screen) {
    if (yoloResults.isEmpty) return [];

    double factorX = screen.width / (imageWidth);
    double imgRatio = imageWidth / imageHeight;
    double newWidth = imageWidth * factorX;
    double newHeight = newWidth / imgRatio;
    double factorY = newHeight / (imageHeight);

    double pady = (screen.height - newHeight) / 2;

    Color colorPick = const Color.fromARGB(255, 50, 233, 30);
    return yoloResults.map((result) {
      return Positioned(
        left: result["box"][0] * factorX,
        top: result["box"][1] * factorY + pady,
        width: (result["box"][2] - result["box"][0]) * factorX,
        height: (result["box"][3] - result["box"][1]) * factorY,
        child: Container(
          decoration: BoxDecoration(
            borderRadius: const BorderRadius.all(Radius.circular(10.0)),
            border: Border.all(color: Colors.pink, width: 2.0),
          ),
          child: Text(
            "${result['tag']} ${(result['box'][4] * 100).toStringAsFixed(0)}%",
            style: TextStyle(
              background: Paint()..color = colorPick,
              color: Colors.white,
              fontSize: 18.0,
            ),
          ),
        ),
      );
    }).toList();
  }
}


flutter object-detection yolov8
1个回答
0
投票

我不是专家,但从我(有限的)经验来看,干预cameraImage值从来没有帮助过我。您是否进行了所有这些转换以获得 yolo 检测?

我花了很多时间进行转换,但最终对我有用的是使我的解决方案适应图像格式。

如果您使用的是 Android,最好使用默认的 YUV_420_888 格式(至少是我的 Pixel 7 Pro 上的默认格式)效果很好。当我将其转换为 NV21 格式时(我需要这样做才能使用 google 的 ml_kit),我必须相应地调整我的输入字节列表。

我改变了:

bytesList: cameraImage.planes.map((plane) => plane.bytes).toList()

至:

bytesList: [image.planes.first.bytes, Uint8List(0), Uint8List(0)]

对该库(一般是颤振库)的在线支持并不是最好的,所以希望这会有所帮助。另外,请确保您正在等待回复

© www.soinside.com 2019 - 2024. All rights reserved.