Skip to content

Commit

Permalink
Merge branch 'master' into feature/rot_comp
Browse files Browse the repository at this point in the history
  • Loading branch information
fbernaly committed Jul 6, 2023
2 parents 010c60c + fa3dc00 commit 0919ae8
Show file tree
Hide file tree
Showing 29 changed files with 969 additions and 11 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/flutter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ jobs:
working-directory: ./packages/google_mlkit_face_detection
run: flutter pub get

- name: Install dependencies for google_mlkit_face_mesh_detection
working-directory: ./packages/google_mlkit_face_mesh_detection
run: flutter pub get

- name: Install dependencies for google_mlkit_image_labeling
working-directory: ./packages/google_mlkit_image_labeling
run: flutter pub get
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Google's ML Kit for Flutter is a set of [Flutter plugins](https://flutter.io/pla
|------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|----|
| [Barcode Scanning](https://developers.google.com/ml-kit/vision/barcode-scanning) | [google\_mlkit\_barcode\_scanning](https://pub.dev/packages/google_mlkit_barcode_scanning) [![Pub Version](https://img.shields.io/pub/v/google_mlkit_barcode_scanning)](https://pub.dev/packages/google_mlkit_barcode_scanning) | [![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/flutter-ml/google_ml_kit_flutter/tree/master/packages/google_mlkit_barcode_scanning) |||
| [Face Detection](https://developers.google.com/ml-kit/vision/face-detection) | [google\_mlkit\_face\_detection](https://pub.dev/packages/google_mlkit_face_detection) [![Pub Version](https://img.shields.io/pub/v/google_mlkit_face_detection)](https://pub.dev/packages/google_mlkit_face_detection) | [![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/flutter-ml/google_ml_kit_flutter/tree/master/packages/google_mlkit_face_detection) |||
| [Face Mesh Detection](https://developers.google.com/ml-kit/vision/face-mesh-detection) | [google\_mlkit\_face\_mesh\_detection](https://pub.dev/packages/google_mlkit_face_mesh_detection) [![Pub Version](https://img.shields.io/pub/v/google_mlkit_face_mesh_detection)](https://pub.dev/packages/google_mlkit_face_mesh_detection) | [![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/flutter-ml/google_ml_kit_flutter/tree/master/packages/google_mlkit_face_mesh_detection) | ||
| [Face Mesh Detection](https://developers.google.com/ml-kit/vision/face-mesh-detection) | [google\_mlkit\_face\_mesh\_detection](https://pub.dev/packages/google_mlkit_face_mesh_detection) [![Pub Version](https://img.shields.io/pub/v/google_mlkit_face_mesh_detection)](https://pub.dev/packages/google_mlkit_face_mesh_detection) | [![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/flutter-ml/google_ml_kit_flutter/tree/master/packages/google_mlkit_face_mesh_detection) | ||
| [Image Labeling](https://developers.google.com/ml-kit/vision/image-labeling) | [google\_mlkit\_image\_labeling](https://pub.dev/packages/google_mlkit_image_labeling) [![Pub Version](https://img.shields.io/pub/v/google_mlkit_image_labeling)](https://pub.dev/packages/google_mlkit_image_labeling) | [![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/flutter-ml/google_ml_kit_flutter/tree/master/packages/google_mlkit_image_labeling) |||
| [Object Detection and Tracking](https://developers.google.com/ml-kit/vision/object-detection) | [google\_mlkit\_object\_detection](https://pub.dev/packages/google_mlkit_object_detection) [![Pub Version](https://img.shields.io/pub/v/google_mlkit_object_detection)](https://pub.dev/packages/google_mlkit_object_detection) | [![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/flutter-ml/google_ml_kit_flutter/tree/master/packages/google_mlkit_object_detection) |||
| [Text Recognition V2](https://developers.google.com/ml-kit/vision/text-recognition/v2) | [google\_mlkit\_text\_recognition](https://pub.dev/packages/google_mlkit_text_recognition) [![Pub Version](https://img.shields.io/pub/v/google_mlkit_text_recognition)](https://pub.dev/packages/google_mlkit_text_recognition) | [![GitHub](https://img.shields.io/badge/github-%23121011.svg?style=for-the-badge&logo=github&logoColor=white)](https://github.com/flutter-ml/google_ml_kit_flutter/tree/master/packages/google_mlkit_text_recognition) |||
Expand Down
7 changes: 7 additions & 0 deletions packages/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ PODS:
- Flutter
- google_mlkit_commons
- GoogleMLKit/FaceDetection (~> 4.0.0)
- google_mlkit_face_mesh_detection (0.0.1):
- Flutter
- google_mlkit_commons
- google_mlkit_image_labeling (0.7.0):
- Flutter
- google_mlkit_commons
Expand Down Expand Up @@ -280,6 +283,7 @@ DEPENDENCIES:
- google_mlkit_digital_ink_recognition (from `.symlinks/plugins/google_mlkit_digital_ink_recognition/ios`)
- google_mlkit_entity_extraction (from `.symlinks/plugins/google_mlkit_entity_extraction/ios`)
- google_mlkit_face_detection (from `.symlinks/plugins/google_mlkit_face_detection/ios`)
- google_mlkit_face_mesh_detection (from `.symlinks/plugins/google_mlkit_face_mesh_detection/ios`)
- google_mlkit_image_labeling (from `.symlinks/plugins/google_mlkit_image_labeling/ios`)
- google_mlkit_language_id (from `.symlinks/plugins/google_mlkit_language_id/ios`)
- google_mlkit_object_detection (from `.symlinks/plugins/google_mlkit_object_detection/ios`)
Expand Down Expand Up @@ -353,6 +357,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/google_mlkit_entity_extraction/ios"
google_mlkit_face_detection:
:path: ".symlinks/plugins/google_mlkit_face_detection/ios"
google_mlkit_face_mesh_detection:
:path: ".symlinks/plugins/google_mlkit_face_mesh_detection/ios"
google_mlkit_image_labeling:
:path: ".symlinks/plugins/google_mlkit_image_labeling/ios"
google_mlkit_language_id:
Expand Down Expand Up @@ -382,6 +388,7 @@ SPEC CHECKSUMS:
google_mlkit_digital_ink_recognition: 07fb2aae2d704592be8f6c2ff63f3adcfd3d768c
google_mlkit_entity_extraction: 480e6029eaacf7fac2305276dc111978bd351bb5
google_mlkit_face_detection: 6930c8cecb10f49921ff7010c165eb1d803e87fd
google_mlkit_face_mesh_detection: 2eeca458203c830b42cfb46de71af317079e65d9
google_mlkit_image_labeling: b338655e8ed02823d06503362c754d6b02537824
google_mlkit_language_id: ee26aec812e70084affbcf628f6c5c7308b1291d
google_mlkit_object_detection: bab13ee252b52eb3bf96db2e88af30c31dd59588
Expand Down
2 changes: 2 additions & 0 deletions packages/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'nlp_detector_views/smart_reply_view.dart';
import 'vision_detector_views/barcode_scanner_view.dart';
import 'vision_detector_views/digital_ink_recognizer_view.dart';
import 'vision_detector_views/face_detector_view.dart';
import 'vision_detector_views/face_mesh_detector_view.dart';
import 'vision_detector_views/label_detector_view.dart';
import 'vision_detector_views/object_detector_view.dart';
import 'vision_detector_views/pose_detector_view.dart';
Expand Down Expand Up @@ -50,6 +51,7 @@ class Home extends StatelessWidget {
children: [
CustomCard('Barcode Scanning', BarcodeScannerView()),
CustomCard('Face Detection', FaceDetectorView()),
CustomCard('Face Mesh Detection', FaceMeshDetectorView()),
CustomCard('Image Labeling', ImageLabelView()),
CustomCard('Object Detection', ObjectDetectorView()),
CustomCard('Text Recognition', TextRecognizerView()),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import 'dart:io';

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:google_mlkit_face_mesh_detection/google_mlkit_face_mesh_detection.dart';

import 'detector_view.dart';
import 'painters/face_mesh_detector_painter.dart';

class FaceMeshDetectorView extends StatefulWidget {
@override
State<FaceMeshDetectorView> createState() => _FaceMeshDetectorViewState();
}

class _FaceMeshDetectorViewState extends State<FaceMeshDetectorView> {
final FaceMeshDetector _meshDetector =
FaceMeshDetector(option: FaceMeshDetectorOptions.faceMesh);
bool _canProcess = true;
bool _isBusy = false;
CustomPaint? _customPaint;
String? _text;
var _cameraLensDirection = CameraLensDirection.front;

@override
void dispose() {
_canProcess = false;
_meshDetector.close();
super.dispose();
}

@override
Widget build(BuildContext context) {
if (Platform.isIOS) {
return Scaffold(
appBar: AppBar(title: Text('Under construction')),
body: Center(
child: Text(
'Not implemented yet for iOS :(\nTry Android',
textAlign: TextAlign.center,
)),
);
}
return DetectorView(
title: 'Face Mesh Detector',
customPaint: _customPaint,
text: _text,
onImage: _processImage,
initialCameraLensDirection: _cameraLensDirection,
onCameraLensDirectionChanged: (value) => _cameraLensDirection = value,
);
}

Future<void> _processImage(InputImage inputImage) async {
if (!_canProcess) return;
if (_isBusy) return;
_isBusy = true;
setState(() {
_text = '';
});
final meshes = await _meshDetector.processImage(inputImage);
if (inputImage.metadata?.size != null &&
inputImage.metadata?.rotation != null) {
final painter = FaceMeshDetectorPainter(
meshes,
inputImage.metadata!.size,
inputImage.metadata!.rotation,
_cameraLensDirection,
);
_customPaint = CustomPaint(painter: painter);
} else {
String text = 'Face meshes found: ${meshes.length}\n\n';
for (final mesh in meshes) {
text += 'face: ${mesh.boundingBox}\n\n';
}
_text = text;
// TODO: set _customPaint to draw boundingRect on top of image
_customPaint = null;
}
_isBusy = false;
if (mounted) {
setState(() {});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import 'dart:ui';

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:google_mlkit_face_mesh_detection/google_mlkit_face_mesh_detection.dart';

import 'coordinates_translator.dart';

class FaceMeshDetectorPainter extends CustomPainter {
FaceMeshDetectorPainter(
this.meshes,
this.imageSize,
this.rotation,
this.cameraLensDirection,
);

final List<FaceMesh> meshes;
final Size imageSize;
final InputImageRotation rotation;
final CameraLensDirection cameraLensDirection;

@override
void paint(Canvas canvas, Size size) {
final Paint paint1 = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1.0
..color = Colors.red;
final Paint paint2 = Paint()
..style = PaintingStyle.fill
..strokeWidth = 1.0
..color = Colors.white;

for (final FaceMesh mesh in meshes) {
final left = translateX(
mesh.boundingBox.left,
size,
imageSize,
rotation,
cameraLensDirection,
);
final top = translateY(
mesh.boundingBox.top,
size,
imageSize,
rotation,
cameraLensDirection,
);
final right = translateX(
mesh.boundingBox.right,
size,
imageSize,
rotation,
cameraLensDirection,
);
final bottom = translateY(
mesh.boundingBox.bottom,
size,
imageSize,
rotation,
cameraLensDirection,
);

canvas.drawRect(
Rect.fromLTRB(left, top, right, bottom),
paint1,
);

void paintTriangle(FaceMeshTriangle triangle) {
final List<Offset> cornerPoints = <Offset>[];
for (final point in triangle.points) {
final double x = translateX(
point.x.toDouble(),
size,
imageSize,
rotation,
cameraLensDirection,
);
final double y = translateY(
point.y.toDouble(),
size,
imageSize,
rotation,
cameraLensDirection,
);

cornerPoints.add(Offset(x, y));
}
// Add the first point to close the polygon
cornerPoints.add(cornerPoints.first);
canvas.drawPoints(PointMode.polygon, cornerPoints, paint2);
}

for (final triangle in mesh.triangles) {
paintTriangle(triangle);
}
}
}

@override
bool shouldRepaint(FaceMeshDetectorPainter oldDelegate) {
return oldDelegate.imageSize != imageSize || oldDelegate.meshes != meshes;
}
}
Loading

0 comments on commit 0919ae8

Please sign in to comment.