TaskConflictGroupBrowser.xaml.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. using aipdev.ViewModel;
  2. using AIPlatform.Protocol.Entities;
  3. using AIPlatform.Protocol.LabelData;
  4. using AIPlatform.Protocol.Model;
  5. using AIPlatform.Protocol.Utilities;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Threading.Tasks;
  12. using System.Windows;
  13. using System.Windows.Controls;
  14. using System.Windows.Media;
  15. using System.Windows.Media.Imaging;
  16. namespace aipdev
  17. {
  18. /// <summary>
  19. /// Interaction logic for TaskConflictGroupBrowser.xaml
  20. /// </summary>
  21. public partial class TaskConflictGroupBrowser : UserControl, IContentPage
  22. {
  23. private ScrollViewer _scrollViewer;
  24. private int _pageSize { get; set; } = 90;
  25. private int _totalPages { get; set; }
  26. private int _currentPage { get; set; }
  27. private bool _scrollDown { get; set; }
  28. private double _oldVerticalOffset { get; set; }
  29. private bool _stopLoading { get; set; }
  30. private readonly ObservableCollection<FileViewModel> _images = new ObservableCollection<FileViewModel>();
  31. private List<GroupResultData> _groupResultDatas = new List<GroupResultData>();
  32. private long _testFolderId { get; set; }
  33. private long _testFolderGroupId { get; set; }
  34. public string PageName { get; set; }
  35. public bool IsHomePage { get; set; }
  36. public bool IsModalPage { get; set; }
  37. public TaskConflictGroupBrowser()
  38. {
  39. InitializeComponent();
  40. PageName = "TaskConflictGroupBrowser";
  41. IsHomePage = false;
  42. IsModalPage = true;
  43. TaskImages.ItemsSource = _images;
  44. }
  45. private T FindVisualChild<T>(DependencyObject element) where T : class
  46. {
  47. try
  48. {
  49. while (element != null)
  50. {
  51. if (element is T)
  52. return element as T;
  53. element = VisualTreeHelper.GetChild(element, 0);
  54. }
  55. }
  56. catch (Exception)
  57. {
  58. //DoNothing
  59. }
  60. return null;
  61. }
  62. private void OnFolderImagesScrollChanged(object sender, ScrollChangedEventArgs e)
  63. {
  64. var scrollViewer = (ScrollViewer)sender;
  65. if (IsOnScrollViewBottom(scrollViewer))
  66. {
  67. if (_currentPage < _totalPages)
  68. {
  69. ContentManager.ShowLoading();
  70. try
  71. {
  72. Task.Run(async () =>
  73. {
  74. await LoadImagesAsync(_currentPage);
  75. });
  76. }
  77. catch (Exception ex)
  78. {
  79. MessageBox.Show(Application.Current.MainWindow, $"加载文件夹图像失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  80. }
  81. finally
  82. {
  83. ContentManager.HideLoading();
  84. }
  85. }
  86. }
  87. }
  88. private bool IsOnScrollViewBottom(ScrollViewer view)
  89. {
  90. var onBottom = false;
  91. var verticalOffset = view.VerticalOffset;
  92. var scrollableHeight = view.ScrollableHeight;
  93. _scrollDown = verticalOffset >= _oldVerticalOffset;
  94. #region 滚动条从上往下翻看,每次加载固定数量
  95. if (_scrollDown && verticalOffset == scrollableHeight && _currentPage < _totalPages - 1)
  96. {
  97. onBottom = true;
  98. verticalOffset = 2;
  99. _currentPage++;
  100. }
  101. #endregion 滚动条从上往下翻看,每次加载固定数量
  102. _oldVerticalOffset = verticalOffset;
  103. return onBottom;
  104. }
  105. public void Close()
  106. {
  107. ClearImages();
  108. }
  109. private async Task LoadImagesAsync(int page = 0)
  110. {
  111. var total = _groupResultDatas.Count;
  112. var num = page * _pageSize + _pageSize;
  113. var count = num > total ? total - page * _pageSize : _pageSize;
  114. var currGroupDatas = _groupResultDatas.GetRange(page * _pageSize, count);
  115. foreach (var currGroupData in currGroupDatas)
  116. {
  117. if (_stopLoading) return;
  118. #region 获取原始图像
  119. var isGetImageData = false;
  120. ArchivedImage currentarchivedImage = null;
  121. byte[] imageData = null;
  122. var index = currGroupData.GroupIndex;
  123. var taskConflictImage = _images.FirstOrDefault(x => x.Index == index);
  124. if (taskConflictImage == null)
  125. {
  126. taskConflictImage = new FileViewModel
  127. {
  128. Index = index,
  129. IsVideo = taskConflictImage.IsVideo,
  130. };
  131. }
  132. if (taskConflictImage.PreviewImage == null)
  133. {
  134. currentarchivedImage = await GetImageData(index);
  135. if (currentarchivedImage == null)
  136. {
  137. break;
  138. }
  139. imageData = currentarchivedImage?.ImageData;
  140. isGetImageData = true;
  141. }
  142. else
  143. {
  144. break;
  145. }
  146. #endregion 获取原始图像
  147. #region 获取图片标注信息并标注
  148. var conclusions = new ObservableCollection<ConflictLabelConclusion>();
  149. var colorIndex = 0;
  150. var currFile = currGroupData.Files.FirstOrDefault(x => x.FileResultInfos.Count > 0);
  151. if (currFile != null)
  152. {
  153. var annotator = currFile.Annotator;
  154. var currResultInfo = currFile.FileResultInfos.FirstOrDefault(x => x.LabeledResult != null);
  155. if (currResultInfo != null)
  156. {
  157. if (_stopLoading) return;
  158. var imageContent = string.Empty;
  159. var roiContent = string.Empty;
  160. var labeledResult = currResultInfo.LabeledResult;
  161. if (labeledResult != null)
  162. {
  163. foreach (var imageResult in labeledResult.ImageResults)
  164. {
  165. var currNum = imageResult.Index + 1;
  166. imageContent += $"[图像标签-{currNum}]-{imageResult.Unit.Title}-{imageResult.Conclusion.Title}";
  167. if (currNum < labeledResult.ImageResults.Count)
  168. {
  169. imageContent += "\r\n";
  170. }
  171. }
  172. foreach (var roi in labeledResult.Rois)
  173. {
  174. if (roi.Conclusion != null)
  175. {
  176. var currNum = roi.Index + 1;
  177. roiContent += $"[ROI-{roi.Index + 1}]-{roi.Unit.Title}-{roi.Conclusion.Title}";
  178. if (currNum < labeledResult.Rois.Count)
  179. {
  180. roiContent += "\r\n";
  181. }
  182. }
  183. }
  184. conclusions.Add(new ConflictLabelConclusion
  185. {
  186. Index = colorIndex,
  187. Annotator = annotator,
  188. ImageContent = imageContent,
  189. RoiContent = roiContent,
  190. LabeledResult = labeledResult,
  191. IsRoi = labeledResult.Rois.Count > 0,
  192. });
  193. colorIndex += 1;
  194. }
  195. if (isGetImageData)
  196. {
  197. imageData = SkiaSharpHelper.GetMultiRectangelLabeledImageData(currentarchivedImage.ImageData, currentarchivedImage.Width, currentarchivedImage.Height, conclusions);
  198. if (imageData != null)
  199. {
  200. var previewImage = new BitmapImage();
  201. previewImage.BeginInit();
  202. previewImage.StreamSource = new MemoryStream(imageData);
  203. previewImage.EndInit();
  204. previewImage.Freeze();
  205. taskConflictImage.PreviewImage = previewImage;
  206. Dispatcher.Invoke(() =>
  207. {
  208. _images.Add(taskConflictImage);
  209. });
  210. }
  211. }
  212. }
  213. }
  214. #endregion 获取图片标注信息并标注
  215. }
  216. Dispatcher.Invoke(() =>
  217. {
  218. if (_scrollViewer == null)
  219. {
  220. _scrollViewer = FindVisualChild<ScrollViewer>(TaskImages);
  221. if (_scrollViewer != null)
  222. {
  223. _scrollViewer.ScrollToTop();
  224. _scrollViewer.ScrollChanged += OnFolderImagesScrollChanged;
  225. }
  226. }
  227. });
  228. }
  229. /// <summary>
  230. /// Get image according to the index
  231. /// </summary>
  232. /// <param name="imageIndex"></param>
  233. /// <returns></returns>
  234. private async Task<ArchivedImage> GetImageData(int imageIndex)
  235. {
  236. try
  237. {
  238. //获取developer folder image
  239. var developerFolderImage = await DeveloperManager.Shared.GetDeveloperFolderFilebyIndexAsync(_testFolderId, _testFolderGroupId, imageIndex);
  240. if (developerFolderImage == null)
  241. {
  242. MessageBox.Show(Application.Current.MainWindow, $"获取测试文件夹图像失败,Index:{imageIndex}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  243. return null;
  244. }
  245. var developerLabeledUltrasoundFile = await DeveloperManager.Shared.GetDeveloperLabeledUltrasoundFileAsync(developerFolderImage.DeveloperLabeledUltrasoundInfoList[0].DeveloperLabeledUltrasoundFileId);
  246. if (developerLabeledUltrasoundFile == null)
  247. {
  248. MessageBox.Show(Application.Current.MainWindow, $"获取测试文件夹标注图像失败,Index:{imageIndex}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  249. return null;
  250. }
  251. var currentarchivedImage = await DeveloperManager.Shared.GetArchivedImageAsync(developerLabeledUltrasoundFile.ArchivedImageId);
  252. if (currentarchivedImage == null)
  253. {
  254. MessageBox.Show(Application.Current.MainWindow, $"获取测试文件夹原始图像失败,Index:{imageIndex}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  255. return null;
  256. }
  257. return currentarchivedImage;
  258. }
  259. catch (Exception ex)
  260. {
  261. MessageBox.Show(Application.Current.MainWindow, $"获取原始图像失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  262. return null;
  263. }
  264. }
  265. private void ClearImages()
  266. {
  267. _scrollViewer ??= FindVisualChild<ScrollViewer>(TaskImages);
  268. if (_scrollViewer != null)
  269. {
  270. _scrollViewer.ScrollChanged -= OnFolderImagesScrollChanged;
  271. }
  272. _stopLoading = true;
  273. _scrollViewer = null;
  274. _images.Clear();
  275. _groupResultDatas.Clear();
  276. _testFolderId = 0;
  277. TaskName.Text = string.Empty;
  278. _currentPage = 0;
  279. _scrollDown = false;
  280. _oldVerticalOffset = 0;
  281. _totalPages = 0;
  282. }
  283. public async void OnShow(object arg)
  284. {
  285. ContentManager.ShowLoading();
  286. try
  287. {
  288. if (arg is TrainTaskEx task)
  289. {
  290. _testFolderId = task.TestFolder.Id;
  291. TaskName.Text = task.Name;
  292. var content = await DeveloperManager.Shared.GetTestResultFromFileAsync(task.Id);
  293. _groupResultDatas = await GetDeserializeGroupResult(content);
  294. if (_groupResultDatas == null || _groupResultDatas.Count == 0)
  295. {
  296. MessageBox.Show(Application.Current.MainWindow, $"没有可供查看的图像", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
  297. return;
  298. }
  299. var count = _groupResultDatas.Count;
  300. _totalPages = count / _pageSize;
  301. if (count % _pageSize != 0)
  302. {
  303. _totalPages++;
  304. }
  305. _stopLoading = false;
  306. _ = Task.Run(async () =>
  307. {
  308. await LoadImagesAsync();
  309. });
  310. }
  311. else
  312. {
  313. throw new InvalidOperationException("无效的文件夹路径。");
  314. }
  315. }
  316. catch (Exception ex)
  317. {
  318. MessageBox.Show(Application.Current.MainWindow, $"加载文件夹图像失败:{ex.Translate()}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
  319. }
  320. finally
  321. {
  322. ContentManager.HideLoading();
  323. }
  324. }
  325. /// <summary>
  326. /// Deserialize the group content
  327. /// </summary>
  328. /// <param name="content"></param>
  329. /// <returns></returns>
  330. private async Task<List<GroupResultData>> GetDeserializeGroupResult(string content)
  331. {
  332. List<GroupResultData> groupResultData = await Task.Run(() =>
  333. {
  334. return Newtonsoft.Json.JsonConvert.DeserializeObject<List<GroupResultData>>(content);
  335. });
  336. return groupResultData;
  337. }
  338. public void OnHide()
  339. {
  340. ClearImages();
  341. }
  342. private void OnImageClick(object sender, RoutedEventArgs e)
  343. {
  344. FileViewModel taskConflictImageEx = null;
  345. if (sender is MenuItem menuItem)
  346. {
  347. taskConflictImageEx = (FileViewModel)menuItem.DataContext;
  348. }
  349. else if (sender is Button button)
  350. {
  351. taskConflictImageEx = (FileViewModel)button.DataContext;
  352. }
  353. if (taskConflictImageEx != null)
  354. {
  355. var folderImageViewer = new TaskConflictGroupViewer(_groupResultDatas, _testFolderId, taskConflictImageEx.Index, 0) { Owner = Application.Current.MainWindow };
  356. folderImageViewer.ShowDialog();
  357. }
  358. }
  359. private void OnCloseClick(object sender, RoutedEventArgs e)
  360. {
  361. ClearImages();
  362. this.Hide();
  363. }
  364. }
  365. }