ai_patint_controller.dart 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import 'dart:convert';
  2. import 'package:fis_measure/interfaces/process/player/play_controller.dart';
  3. import 'package:fis_measure/interfaces/process/workspace/application.dart';
  4. import 'package:fis_measure/process/workspace/measure_data_controller.dart';
  5. import 'package:fis_measure/view/paint/ai_patint_state.dart';
  6. import 'package:fis_measure/view/paint/date_structure.dart';
  7. import 'package:fis_measure/view/player/controller.dart';
  8. import 'package:fis_measure/view/player/enums.dart';
  9. import 'package:flutter/material.dart';
  10. import 'package:get/get.dart';
  11. class AiPatintController extends GetxController {
  12. static const _HAS_VIEW_STATUS_ARR = [VidPlayStatus.play, VidPlayStatus.pause];
  13. /// 播放器控制器
  14. final VidPlayerController controller;
  15. final state = AiPatintState();
  16. late final application = Get.find<IApplication>();
  17. /// ai结果
  18. // late final List<AIDiagnosisPerImageDTO> aiResult = [];
  19. /// 测量AI数据
  20. final measureData = Get.find<MeasureDataController>();
  21. /// 播放控制器
  22. final playerController = Get.find<IPlayerController>();
  23. /// ai结果图展示
  24. late List<Offset> aiResultsList = [];
  25. /// ai结果数据
  26. late List<AIDetectedObject> aiDetectedObject = [];
  27. /// ai部位
  28. late DiagnosisOrganEnum diagnosisOrgan = DiagnosisOrganEnum.Null;
  29. /// 是否是播放状态
  30. get isPlay => playerController.status == VidPlayStatus.play;
  31. /// ai json 数据
  32. late String? aiResults = '';
  33. /// ai的横纵坐标 四个点
  34. late Offset p1 = Offset.zero;
  35. late Offset p2 = Offset.zero;
  36. late Offset p3 = Offset.zero;
  37. late Offset p4 = Offset.zero;
  38. /// 视频时的画面
  39. double left = -1;
  40. double top = -1;
  41. double width = -1;
  42. double height = -1;
  43. /// 当前帧数
  44. int? frameIndex;
  45. /// ai结果下标
  46. // int aiResultIndex = 0;
  47. AiPatintController(this.controller);
  48. @override
  49. void onInit() {
  50. _addListenrs();
  51. super.onInit();
  52. }
  53. void onMeasuredAIResultsInfoChanged(Object sender, String e) {
  54. if (e.isNotEmpty && e != "[]") {
  55. aiResults = e;
  56. final measureDataAIResults = jsonDecode(
  57. aiResults ?? '',
  58. );
  59. state.aiResult.clear();
  60. for (int i = 0; i < (measureDataAIResults as List).length; i++) {
  61. state.aiResult.add(
  62. AIDiagnosisPerImageDTO.fromJson(
  63. measureDataAIResults[i],
  64. ),
  65. );
  66. }
  67. } else {
  68. aiResults = '';
  69. state.aiResult.clear();
  70. }
  71. }
  72. /// 单帧图处理
  73. void onSingleFrameImage(
  74. List<AIDetectedObject>? detectedObjects,
  75. DiagnosisOrganEnum organ,
  76. double widthScale,
  77. ) {
  78. aiDetectedObject = detectedObjects ?? [];
  79. diagnosisOrgan = organ;
  80. for (int m = 0; m < detectedObjects!.length; m++) {
  81. final List<AIDiagnosisPoint2D>? contours = detectedObjects[m].contours;
  82. if (contours!.isNotEmpty && detectedObjects[m].descriptions!.isNotEmpty) {
  83. final descriptions = jsonDecode(
  84. detectedObjects[m]
  85. .descriptions![detectedObjects[m].descriptions!.length - 1]
  86. .value!,
  87. );
  88. if (_HAS_VIEW_STATUS_ARR
  89. .contains((playerController as VidPlayerController).status)) {
  90. for (int i = 0; i < contours.length; i++) {
  91. if (i % 10 == 0) {
  92. aiResultsList.add(Offset(
  93. contours[i].x * widthScale,
  94. contours[i].y * widthScale,
  95. ));
  96. }
  97. }
  98. p1 = Offset(descriptions['HorizontalPoint1']['X'] * widthScale,
  99. descriptions['HorizontalPoint1']['Y'] * widthScale);
  100. p2 = Offset(descriptions['HorizontalPoint2']['X'] * widthScale,
  101. descriptions['HorizontalPoint2']['Y'] * widthScale);
  102. p3 = Offset(descriptions['VerticalPoint1']['X'] * widthScale,
  103. descriptions['VerticalPoint1']['Y'] * widthScale);
  104. p4 = Offset(descriptions['VerticalPoint2']['X'] * widthScale,
  105. descriptions['VerticalPoint2']['Y'] * widthScale);
  106. }
  107. }
  108. }
  109. }
  110. /// ai处理图片结果
  111. bool onGetAIResultsInfo(double widthScale) {
  112. if (state.aiResult.isEmpty) {
  113. return false;
  114. } else if (state.aiResult.length == 1) {
  115. final diagResultsForEachOrgan =
  116. state.aiResult[0].diagResultsForEachOrgan?[state.aiResultIndex];
  117. final detectedObjects = diagResultsForEachOrgan!.detectedObjects;
  118. final diagnosisOrgan = diagResultsForEachOrgan.organ;
  119. _updateFeatures();
  120. if (detectedObjects!.isNotEmpty) {
  121. onSingleFrameImage(
  122. detectedObjects,
  123. diagnosisOrgan,
  124. widthScale,
  125. );
  126. } else {
  127. return false;
  128. }
  129. return true;
  130. } else {
  131. _updateFeatures();
  132. final diagResultsForEachOrgan = state.aiResult[state.frameIndex!]
  133. .diagResultsForEachOrgan![state.aiResultIndex];
  134. final detectedObjects = diagResultsForEachOrgan.detectedObjects;
  135. final diagnosisOrgan = diagResultsForEachOrgan.organ;
  136. if ((playerController as VidPlayerController).status ==
  137. VidPlayStatus.pause) {
  138. if (detectedObjects!.isNotEmpty) {
  139. onSingleFrameImage(
  140. detectedObjects,
  141. diagnosisOrgan,
  142. widthScale,
  143. );
  144. }
  145. } else if (isPlay) {
  146. for (int m = 0; m < detectedObjects!.length; m++) {
  147. final organBoundBox = detectedObjects[m].boundingBox;
  148. left = organBoundBox!.left * widthScale;
  149. top = organBoundBox.top * widthScale;
  150. width = organBoundBox.width * widthScale;
  151. height = organBoundBox.height * widthScale;
  152. }
  153. }
  154. return true;
  155. }
  156. }
  157. void _updateFeatures() {
  158. aiResultsList = [];
  159. left = 0;
  160. top = 0;
  161. width = 0;
  162. height = 0;
  163. p1 = Offset.zero;
  164. p2 = Offset.zero;
  165. p3 = Offset.zero;
  166. p4 = Offset.zero;
  167. }
  168. void _onMeasureRerenderReady(Object sender, void e) async {
  169. update();
  170. }
  171. void _addListenrs() async {
  172. application.updateRenderReady.addListener(_onMeasureRerenderReady);
  173. measureData.aiResultsInfoChanged
  174. .addListener(onMeasuredAIResultsInfoChanged);
  175. if (measureData.aiResults.isNotEmpty) {
  176. onMeasuredAIResultsInfoChanged(this, measureData.aiResults);
  177. }
  178. }
  179. void _removeListenrs() {
  180. application.updateRenderReady.removeListener(_onMeasureRerenderReady);
  181. measureData.aiResultsInfoChanged
  182. .removeListener(onMeasuredAIResultsInfoChanged);
  183. }
  184. }