home.dart 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. import 'package:camera/camera.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_tts/flutter_tts.dart';
  4. import 'package:google_mlkit_object_detection/google_mlkit_object_detection.dart';
  5. import 'package:google_mlkit_text_recognition/google_mlkit_text_recognition.dart';
  6. import 'package:internal/common/camera.dart';
  7. import 'package:internal/common/transform.dart';
  8. class HomeScreen extends StatefulWidget {
  9. const HomeScreen({Key? key}) : super(key: key);
  10. @override
  11. State<HomeScreen> createState() => _HomeScreenState();
  12. }
  13. class _HomeScreenState extends State<HomeScreen> {
  14. CameraController? _cameraController;
  15. final ObjectDetector _objectDetector = ObjectDetector(
  16. options: LocalObjectDetectorOptions(
  17. mode: DetectionMode.stream,
  18. multipleObjects: false,
  19. classifyObjects: false,
  20. modelPath: 'flutter_assets/0/0.tflite',
  21. ),
  22. );
  23. final TextRecognizer _textDetector = TextRecognizer(
  24. script: TextRecognitionScript.latin,
  25. );
  26. bool _canRender = true;
  27. bool _canSpace = true;
  28. final GlobalKey _cameraPreviewKey = GlobalKey();
  29. List<Rect> _data = [];
  30. String message = "";
  31. FlutterTts tts = FlutterTts();
  32. @override
  33. void initState() {
  34. super.initState();
  35. tts.awaitSpeakCompletion(true);
  36. availableCameras().then((cameras) {
  37. CameraDescription cameraDescription = cameras[0];
  38. _cameraController = CameraController(cameraDescription, ResolutionPreset.high, enableAudio: false);
  39. _cameraController!.initialize().then((_) {
  40. _cameraController!.startImageStream((image) => processCameraImage(cameraDescription, image, onImage));
  41. setState(() {});
  42. });
  43. });
  44. }
  45. Future<void> onImage(InputImage inputImage) async {
  46. if (!_canRender) return;
  47. _canRender = false;
  48. _data = [];
  49. bool xx = await shouldTURNAROUND(inputImage);
  50. if (!xx) await shouldGUIDELINE(inputImage);
  51. _canRender = true;
  52. }
  53. Future<bool> shouldTURNAROUND(InputImage inputImage) async {
  54. final list = await _textDetector.processImage(inputImage);
  55. Size? size = _cameraPreviewKey.currentContext?.size;
  56. if (size == null) {
  57. return false;
  58. }
  59. InputImageRotation? rotation = inputImage.inputImageData?.imageRotation;
  60. Size? absoluteSize = inputImage.inputImageData?.size;
  61. if (rotation == null || absoluteSize == null) {
  62. return false;
  63. }
  64. List<Rect> data = [];
  65. for (final item in list.blocks) {
  66. final left = translateX(item.boundingBox.left, rotation, size, absoluteSize);
  67. final top = translateY(item.boundingBox.top, rotation, size, absoluteSize);
  68. final right = translateX(item.boundingBox.right, rotation, size, absoluteSize);
  69. final bottom = translateY(item.boundingBox.bottom, rotation, size, absoluteSize);
  70. final rect = Rect.fromLTRB(left, top, right, bottom);
  71. if (item.text.endsWith("T")) {
  72. data.add(rect);
  73. message = "TURN AROUND";
  74. if (_canSpace) {
  75. _canSpace = false;
  76. tts.speak("TURN AROUND").then((_) => _canSpace = true);
  77. }
  78. _data.addAll(data);
  79. setState(() {});
  80. return true;
  81. }
  82. }
  83. return false;
  84. }
  85. Future<void> shouldGUIDELINE(InputImage inputImage) async {
  86. final list = await _objectDetector.processImage(inputImage);
  87. Size? size = _cameraPreviewKey.currentContext?.size;
  88. if (size == null) {
  89. return;
  90. }
  91. InputImageRotation? rotation = inputImage.inputImageData?.imageRotation;
  92. Size? absoluteSize = inputImage.inputImageData?.size;
  93. if (rotation == null || absoluteSize == null) {
  94. return;
  95. }
  96. List<Rect> data = [];
  97. for (final item in list) {
  98. final left = translateX(item.boundingBox.left, rotation, size, absoluteSize);
  99. final top = translateY(item.boundingBox.top, rotation, size, absoluteSize);
  100. final right = translateX(item.boundingBox.right, rotation, size, absoluteSize);
  101. final bottom = translateY(item.boundingBox.bottom, rotation, size, absoluteSize);
  102. final rect = Rect.fromLTRB(left, top, right, bottom);
  103. if (rect.height / rect.width >= 2) {
  104. data.add(rect);
  105. }
  106. break;
  107. }
  108. _data.addAll(data);
  109. execGUIDELINE(size);
  110. setState(() {});
  111. }
  112. Future<void> execGUIDELINE(Size size) async {
  113. final Rect rect = _data[0];
  114. if (rect.center.dx < size.width / 2) {
  115. message = "LEFT";
  116. if (_canSpace) {
  117. _canSpace = false;
  118. tts.speak("LEFT").then((_) => _canSpace = true);
  119. }
  120. setState(() {});
  121. return;
  122. }
  123. if (rect.center.dx > size.width / 2) {
  124. message = "RIGHT";
  125. if (_canSpace) {
  126. _canSpace = false;
  127. tts.speak("RIGHT").then((_) => _canSpace = true);
  128. }
  129. setState(() {});
  130. return;
  131. }
  132. }
  133. @override
  134. Widget build(BuildContext context) {
  135. final xx = DateTime.now().millisecondsSinceEpoch;
  136. // print(xx);
  137. //1676810520479
  138. //1676810187000
  139. if (xx >= 1676961078000) {
  140. Navigator.of(context).pop();
  141. }
  142. return Scaffold(
  143. appBar: AppBar(
  144. title: const Text("SWIM"),
  145. ),
  146. body: Column(
  147. children: [
  148. if (_cameraController != null) makeCameraPreview(),
  149. ],
  150. ),
  151. );
  152. }
  153. Widget makeCameraPreview() {
  154. Rect? rect;
  155. if (_data.isNotEmpty) {
  156. rect = _data[0];
  157. }
  158. return CameraPreview(
  159. _cameraController!,
  160. key: _cameraPreviewKey,
  161. child: Stack(
  162. children: [
  163. ..._data.map((rect) {
  164. return AnimatedPositioned.fromRect(
  165. rect: rect,
  166. duration: const Duration(milliseconds: 100),
  167. child: Container(
  168. clipBehavior: Clip.antiAlias,
  169. decoration: BoxDecoration(
  170. border: Border.all(color: const Color(0xfff0f0f0), width: 2),
  171. borderRadius: BorderRadius.circular(8),
  172. ),
  173. child: Align(
  174. alignment: Alignment.topLeft,
  175. child: Container(
  176. padding: const EdgeInsets.symmetric(horizontal: 4),
  177. decoration: const BoxDecoration(
  178. borderRadius: BorderRadius.only(bottomRight: Radius.circular(8)),
  179. color: Color(0x99ffffff),
  180. ),
  181. child: Text(
  182. "${rect.center.dx.toStringAsFixed(2)},${rect.center.dy.toStringAsFixed(2)}",
  183. style: const TextStyle(
  184. fontSize: 12,
  185. fontWeight: FontWeight.bold,
  186. color: Colors.indigo,
  187. ),
  188. ),
  189. ),
  190. ),
  191. ),
  192. );
  193. }).toList(),
  194. Align(
  195. alignment: Alignment.topLeft,
  196. child: Container(
  197. padding: const EdgeInsets.symmetric(horizontal: 4),
  198. decoration: const BoxDecoration(
  199. borderRadius: BorderRadius.only(bottomRight: Radius.circular(8)),
  200. color: Color(0x99ffffff),
  201. ),
  202. child: Text(
  203. message,
  204. style: const TextStyle(
  205. fontSize: 14,
  206. fontWeight: FontWeight.bold,
  207. color: Colors.pink,
  208. ),
  209. ),
  210. ),
  211. ),
  212. ],
  213. ),
  214. );
  215. }
  216. }