Обработать изображение с камеры в флаттере - PullRequest
1 голос
/ 22 марта 2020

Я пытаюсь обработать ввод изображения с камеры во Flutter, но не могу заставить его работать.

У меня есть прослушиватель на канале камеры, который запускает функцию, которая должна обрабатывать Изображения btu каждый раз, когда я делаю что-нибудь в функции, интерфейс программы зависает. Я предполагаю, что у меня слишком много кадров для обработки, и поэтому программа зависает, но я не знаю, как игнорировать старые кадры.

Вот мой код до сих пор

import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:image/image.dart' as imglib;
import 'package:flutter/scheduler.dart';
import 'user_data_container.dart';


class Camera extends StatefulWidget {

  Camera();

  @override
  _CameraState createState() => new _CameraState();
}

class _CameraState extends State<Camera> {
  CameraController controller;
  bool isDetecting = false;
  double redavg;
  imglib.Image last_image;
  int count = 0;

  Image _image_display;

  @override
  void initState() {
    super.initState();
    SchedulerBinding.instance.addPostFrameCallback((_) {
      _initializeApp();
    });
  }

  void _initializeApp() async {
    var cameras = UserDataContainer.of(context).data.cameras;
    if (cameras == null || cameras.length < 1) {
      print('No camera is found');
    } else {
      controller = new CameraController(
        cameras[0],
        ResolutionPreset.high,
      );
      controller.initialize().then((_) {
        if (!mounted) {
          return;
        }
        setState(() {});

        controller.startImageStream((CameraImage img) async {
          print(count.toString() + "Stream. detecting: " + isDetecting.toString());
          if (!isDetecting) {
            isDetecting = true;

            int startTime = new DateTime.now().millisecondsSinceEpoch;
            _processCameraImage(img);
//            int endTime = new DateTime.now().millisecondsSinceEpoch;

//            print("Detection done in " + (endTime - startTime).toString());
//            isDetecting = false;
          }
          else{
            print("It's detecting");
          }
        });
      });
    }
  }

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

  @override
  Widget build(BuildContext context) {
    if (controller == null || !controller.value.isInitialized) {
      return Container();
    }


    return

      Scaffold(
        body: Column(
          children: <Widget>[
            Text("red: "+ redavg.toString() + " "+ count.toString()),
            Expanded(child: last_image == null ? Container() : _image_display),
          ],
        ),
      );

//    );
  }

  void _processCameraImage(CameraImage image) async {
    count = count +1;
    print("p: " + image.planes.length.toString());
//    if (isDetecting) {
//      print("Already detecting;");
//      return;
//    }
//    else{
//      isDetecting = true;
      try {
        await processFrame(image);
      } catch (e) {
        // await handleExepction(e)
      } finally {
        print("Done detecting :)");
//        isDetecting = false;
      }
//    }



  }

  void processFrame(CameraImage image) async {
    print ("convert");
    imglib.Image convertedImage = await _convertCameraImage(image);
    last_image = convertedImage;

    imglib.PngEncoder pngEncoder = new imglib.PngEncoder(level: 0, filter: 0);
    // Convert to png
    List<int> png = pngEncoder.encodeImage(last_image);
    _image_display = Image.memory(png);


//    var colors = colorAverage(convertedImage);
    setState(() {
//      redavg = colors[2];
//      print(colors.toString());
    });
  }


  imglib.Image _convertCameraImage(CameraImage image) {
    int width = image.width;
    int height = image.height;
    var img = imglib.Image(image.planes[0].bytesPerRow, height); // Create Image buffer
    const int hexFF = 0xFF000000;
    final int uvyButtonStride = image.planes[1].bytesPerRow;
    final int uvPixelStride = image.planes[1].bytesPerPixel;
    for (int x = 0; x < width; x++) {
      for (int y = 0; y < height; y++) {
        final int uvIndex =
            uvPixelStride * (x / 2).floor() + uvyButtonStride * (y / 2).floor();
        final int index = y * width + x;
        final yp = image.planes[0].bytes[index];
        final up = image.planes[1].bytes[uvIndex];
        final vp = image.planes[2].bytes[uvIndex];
        // Calculate pixel color
        int r = (yp + vp * 1436 / 1024 - 179).round().clamp(0, 255);
        int g = (yp - up * 46549 / 131072 + 44 - vp * 93604 / 131072 + 91)
            .round()
            .clamp(0, 255);
        int b = (yp + up * 1814 / 1024 - 227).round().clamp(0, 255);
        // color: 0x FF  FF  FF  FF
        //           A   B   G   R
        img.data[index] = hexFF | (b << 16) | (g << 8) | r;
      }
    }
    // Rotate 90 degrees to upright
//    var img1 = imglib.copyRotate(img, 90);

    imglib.PngEncoder pngEncoder = new imglib.PngEncoder(level: 0, filter: 0);
    // Convert to png
    List<int> png = pngEncoder.encodeImage(img);
    _image_display = Image.memory(png);

    return img;
  }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...