Notice
Recent Posts
Recent Comments
Link
250x250
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

혼자서 앱 만드는 개발자 함께하는 AI 세상

플러터 카메라 실시간데이터 처리를 위한 startImageStream 본문

딥러닝 머신러닝

플러터 카메라 실시간데이터 처리를 위한 startImageStream

혼앱사 2023. 7. 27. 07:46
반응형

이미지 학습된 데이터를 이용해서 플러터 앱을 통해 실시간 이미지를 분리하는 작업을 하려면 카메라컨트럴러의 startimageStream 을 이용한다.

기존에 구글링소스를 적용하다 최신 dart(3.0.6) flutter(3.10.6) 버전이랑 맞지 않아서 찾아서 수정하는데 어려움이 있어서 다시 작성해서 올려본다.

카메라컨트럴러 선언

 

컨트럴러 작동 매핑

아래코드를 통해 실시간으로 이미지가 처리되는것을 알수있다.

 void _processImageFromStream(CameraImage image) {
    print(image.planes[0].bytes[0]);

    _savedImage = image;
  }

실시간 카메라가 돌아가는 중간 클릭해서 카메라 이미지를 png이미지로 변환 한다.

   FloatingActionButton(
                  onPressed: () {
                    convertImageToPng(_savedImage);
                  },
                  tooltip: 'Increment',
                  child: Icon(Icons.camera_alt),
                ),

bgra 포멧과 yuv 포멧에 따라 (저의폰의 경우 yuv포멧)


  Future<Uint8List?> convertImageToPng(CameraImage image) async {
    Uint8List? bytes;
    controller.stopImageStream();
    try {
      imglib.Image img;
      if (image.format.group == ImageFormatGroup.bgra8888) {
        img = _convertBGRA8888(image);
        imglib.PngEncoder pngEncoder = new imglib.PngEncoder();
        bytes = pngEncoder.encode(img);
      } else {
        bytes = await convertYUV420toImageColor(image);
        print(bytes);
        _image = bytes!;
      }
      print(bytes);
      return bytes;
    } catch (e) {
      print(">>>>>>>>>>>> ERROR:" + e.toString());
    }
    return null;
  }

 

아래 각각 소스로변형시켤수 있다.


  imglib.Image _convertBGRA8888(CameraImage image) {
    return imglib.Image.fromBytes(
        width: image.width,
        height: image.height,
        bytes: image.planes[0].bytes.buffer,
        order: imglib.ChannelOrder.bgra);
  }

  Future<Uint8List> convertImageToJPG(CameraImage image) async {
    YuvChannelling _yuvChannelling = YuvChannelling();
    Uint8List imgJpeg = await _yuvChannelling.yuv_transform(image);
    return imgJpeg;
  }

  static const shift = (0xFF << 24);
  Future<Uint8List?> convertYUV420toImageColor(CameraImage image) async {
    try {
      final int width = image.width;
      final int height = image.height;
      final int uvRowStride = image.planes[1].bytesPerRow;
      final int? uvPixelStride = image.planes[1].bytesPerPixel;

      print("uvRowStride: " + uvRowStride.toString());
      print("uvPixelStride: " + uvPixelStride.toString());

      // imgLib -> Image package from https://pub.dartlang.org/packages/image
      var img =
          imglib.Image(width: width, height: height); // Create Image buffer

      // Fill image buffer with plane[0] from YUV420_888
      for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
          final int uvIndex =
              uvPixelStride! * (x / 2).floor() + uvRowStride * (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] = shift | (b << 16) | (g << 8) | r;

          if (img.isBoundsSafe(height - y, x)) {
            img.setPixelRgba(height - y, x, r, g, b, shift);
          }
        }
      }

      var pngEncoder = imglib.PngEncoder(level: 0);
      var png = pngEncoder.encode(img);
      //  muteYUVProcessing = false;
      //return Image.memory(png);
      return png;
    } catch (e) {
      print(">>>>>>>>>>>> ERROR:" + e.toString());
    }
    return null;
  }

  imglib.Image _convertYUV420(CameraImage image) {
    var img = imglib.Image(
        width: image.width, height: image.height); // Create Image buffer

    Plane plane = image.planes[0];

    const int shift = (0xFF << 24);

    // Fill image buffer with plane[0] from YUV420_888

    for (int x = 0; x < image.width; x++) {
      for (int planeOffset = 0;
          planeOffset < image.height * image.width;
          planeOffset += image.width) {
        final pixelColor = plane.bytes[planeOffset + x];

        // color: 0x FF  FF  FF  FF

        //           A   B   G   R

        // Calculate pixel color

        var newVal =
            shift | (pixelColor << 16) | (pixelColor << 8) | pixelColor;

        //img.data?[planeOffset + x] = newVal;
      }
    }

    return img;
  }

 

728x90
반응형
Comments