gt_file_generate.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. """
  2. 将平台的标注信息,装换成所需要的gt格式文件
  3. 分为分类,检测,语义分割,三种不同的格式
  4. 后续添加实例分割的格式,直接添加函数即可
  5. """
  6. import json
  7. import numpy as np
  8. """
  9. 将平台的标注格式转成计算metrics所需的格式
  10. 平台提供的label_info标注格式,注释如下:"Rois"中存放roi标签,"ImageResults"中存放图像标签
  11. {
  12. "Id": " ",
  13. "Rois":
  14. [
  15. {
  16. "Id": " ",
  17. "Index": 0,
  18. "Points": [ "254, 122", "253, 122" ],
  19. "Descriptions": [],
  20. "Conclusion":
  21. {
  22. "Id": " ",
  23. "Title": " ",
  24. "IsRegion": false,
  25. "IsUnique": false
  26. },
  27. "Unit":
  28. {
  29. "Id": " ",
  30. "Title": " ",
  31. "RegionRequired": false
  32. }
  33. }
  34. ,
  35. {多个roi标签时,多个表示,"Index"需要调整加1}
  36. ],
  37. "ImageResults":
  38. [
  39. {
  40. "Id": "waTJBlDmo8Oj4xvh",
  41. "Index": 0,
  42. "Descriptions": [],
  43. "Conclusion":
  44. {
  45. "Id": "",
  46. "Title": "",
  47. "IsRegion": false,
  48. "IsUnique": false
  49. },
  50. "Unit":
  51. {
  52. "Id": "8YhRbEaKl10woNgM",
  53. "Title": "肝脏",
  54. "RegionRequired": false
  55. }
  56. }
  57. ,
  58. {多个图像标签时,多个表示,"Index"需要调整加1}
  59. ],
  60. "Unit":
  61. {
  62. "Id": " ",
  63. "Title": " ",
  64. "RegionRequired": false
  65. }
  66. }
  67. 预测metrics所需的格式:
  68. 分类:
  69. [{'Label': 0, 'Confidence': 1.0}]
  70. []
  71. 检测:
  72. [{'Label': 1, 'Confidence': 1.0, 'BoundingBox':[2, 3, 4, 5]}]
  73. [{'Label': 1, 'Confidence': 1.0, 'BoundingBox':[2, 3, 4, 5]},{'Label': 2, 'Confidence': 1.0, 'BoundingBox':[2, 3, 4, 5]}]
  74. [{'Label': 0, 'Confidence': 1.0, 'BoundingBox':[0, 0, 0, 0]}]
  75. []
  76. 语义分割:
  77. [{'Label': 0, 'Confidence': 1.0, 'Image_size':[w, h], 'Contour': []}]
  78. [{'Label': 1, 'Confidence': 1.0, 'Image_size':[w, h], 'Contours':[ [ [1,2],[3,4] ] , [ [5,6],[7,8] ] ]}]
  79. [{'Label': 1, 'Confidence': 1.0, 'Image_size':[w, h], 'Contours':[ [ [1,2],[3,4] ] ]}]
  80. [{'Label': 1, 'Confidence': 1.0, ''Image_size':[w, h], Contours':[ [ [1,2],[3,4] ] ]},{'Label': 2, 'Confidence': 1.0, 'Contours':[ [ [1,2],[3,4] ] ]}]
  81. []
  82. """
  83. def gtfilegenerate_classifications(label_info,
  84. image_size,
  85. needed_imageresults_dict,
  86. needed_rois_dict,
  87. class_id_map):
  88. """
  89. 设置所需的gt格式,返回需要的json格式
  90. 适用于:导航的分类网络,判断乳腺腹部等扫查部分分类网络
  91. :param label_info:平台提供的label_info标注格式
  92. :param needed_imageresults_dict: 图像标签
  93. :param needed_rois_dict: roi标签
  94. :param class_id_map: 用于label改变的dict
  95. :return: 返回gt的json格式文件
  96. output_info = {'Label': 0, 'Confidence': 1.0}
  97. """
  98. labeled_result = label_info[0]["FileResultInfos"][0]["LabeledResult"]
  99. output_info_list = []
  100. # 图像标签判断
  101. for image_result in labeled_result["ImageResults"]:
  102. image_cls = image_result["Conclusion"]["Title"]
  103. if image_cls in needed_imageresults_dict.keys():
  104. output_info = {'Label': 0, 'Confidence': 1.0}
  105. output_info['Label'] = class_id_map[needed_imageresults_dict[image_cls]]
  106. output_info_list.append(output_info)
  107. # roi标签判断
  108. for each_roi_label in label_info["Rois"]:
  109. roi_cls = each_roi_label["Conclusion"]["Title"]
  110. if roi_cls in needed_rois_dict.keys():
  111. output_info = {'Label': 0,
  112. 'Confidence': 1.0}
  113. output_info['Label'] = class_id_map[needed_rois_dict[roi_cls]]
  114. output_info_list.append(output_info)
  115. # 保证输出的output_info_list
  116. if len(output_info_list) == 0:
  117. print('label_info为:{} 的图像,无法匹配任何所需的imageresults和rois的title,该图像作废'.format(label_info))
  118. return json.dumps([], ensure_ascii=False)
  119. elif len(output_info_list) > 1:
  120. print('label_info为:{} 的图像,图像匹配多个imageresults和rois的title,该图像作废'.format(label_info))
  121. return json.dumps([], ensure_ascii=False)
  122. else:
  123. return json.dumps(output_info_list, ensure_ascii=False)
  124. def gtfilegenerate_classifications_liverdiffuselesionclassifier(label_info,
  125. image_size,
  126. needed_imageresults_dict,
  127. needed_rois_dict,
  128. class_id_map):
  129. """
  130. 设置所需的gt格式,返回需要的json格式
  131. 适用于:肝脏弥漫性疾病分类
  132. :param label_info:平台提供的label_info标注格式
  133. :param needed_imageresults_dict: 图像标签
  134. :param needed_rois_dict: roi标签
  135. :param class_id_map: 用于label改变的dict
  136. :return: 返回gt的json格式文件
  137. output_info = {'Label': 0, 'Confidence': 1.0}
  138. """
  139. labeled_result = label_info[0]["FileResultInfos"][0]["LabeledResult"]
  140. output_info_list = []
  141. temp_list = []
  142. # roi标签判断
  143. for each_roi_label in range(len(labeled_result["Rois"])):
  144. roi_cls = each_roi_label["Conclusion"]["Title"]
  145. if roi_cls in needed_rois_dict.keys():
  146. output_info = {'Label': 0,
  147. 'Confidence': 1.0}
  148. output_info['Label'] = class_id_map[needed_rois_dict[roi_cls]]
  149. output_info_list.append(output_info)
  150. temp_list.append(roi_cls)
  151. # 肝脏弥漫性分类,比较特殊,因为标注问题,会出现:标注一个肝的轮廓,再标注一个弥漫性疾病的情况,分类标签无法确定
  152. # 根据rois标签的title,将'肝脏未见明显异常'删除
  153. if len(output_info_list) == 2 and len(temp_list) == 2:
  154. for roi_cls in temp_list:
  155. if roi_cls == '肝脏未见明显异常':
  156. output_info_list.pop(temp_list.index(roi_cls))
  157. # 保证输出的output_info_list
  158. if len(output_info_list) == 0:
  159. print('label_info为:{} 的图像,无法匹配任何所需的imageresults和rois的title,该图像作废'.format(label_info))
  160. return json.dumps([], ensure_ascii=False)
  161. elif len(output_info_list) > 1:
  162. print('label_info为:{} 的图像,图像匹配多个imageresults和rois的title,该图像作废'.format(label_info))
  163. return json.dumps([], ensure_ascii=False)
  164. else:
  165. return json.dumps(output_info_list, ensure_ascii=False)
  166. def gtfilegenerate_objectdetection(label_info,
  167. image_size,
  168. needed_imageresults_dict,
  169. needed_rois_dict,
  170. class_id_map):
  171. """
  172. 设置所需的gt格式,返回需要的json格式
  173. 适用于: 乳腺检测,肝脏局灶性疾病检测
  174. :param label_info:平台提供的label_info标注格式
  175. :param needed_imageresults_dict: 图像标签
  176. :param needed_rois_dict: roi标签
  177. :param class_id_map: 用于label改变的dict
  178. :return: 返回gt的json格式文件
  179. output_info = {'Label': 0, 'Confidence': 1.0, 'BoundingBox':[0, 0, 0, 0]}
  180. output_info = {'Label': 1, 'Confidence': 1.0, 'BoundingBox':[2, 3, 4, 5]}
  181. BoundingBox格式:left,top,right,bottom
  182. """
  183. labeled_result = label_info[0]["FileResultInfos"][0]["LabeledResult"]
  184. output_info_list = []
  185. # 图像标签判断
  186. for image_result in labeled_result["ImageResults"]:
  187. image_cls = image_result["Conclusion"]["Title"]
  188. if image_cls in needed_imageresults_dict.keys():
  189. output_info = {'Label': class_id_map[needed_imageresults_dict[image_cls]],
  190. 'Confidence': 1.0,
  191. 'BoundingBox': [0, 0, 0, 0]}
  192. output_info_list.append(output_info)
  193. for each_roi_label in labeled_result["Rois"]:
  194. roi_cls = each_roi_label["Conclusion"]["Title"]
  195. if roi_cls in needed_rois_dict.keys():
  196. roi_points = each_roi_label["Points"]
  197. x, y = [], []
  198. for point in roi_points:
  199. x.append(int(point["X"]))
  200. y.append(int(point["Y"]))
  201. left, right = min(x), max(x)
  202. top, bottom = min(y), max(y)
  203. roi_boundingbox = [left, top, right, bottom]
  204. output_info = {'Label': class_id_map[needed_rois_dict[roi_cls]],
  205. 'Confidence': 1.0,
  206. 'BoundingBox': roi_boundingbox}
  207. output_info_list.append(output_info)
  208. # 保证输出的output_info_list
  209. if len(output_info_list) == 0:
  210. print('label_info为:{} 的图像,无法匹配任何所需的imageresults和rois的title,该图像作废'.format(label_info))
  211. return json.dumps([], ensure_ascii=False)
  212. else:
  213. return json.dumps(output_info_list, ensure_ascii=False)
  214. def gtfilegenerate_objectdetection_liverfocalobd(label_info,
  215. image_size,
  216. needed_imageresults_dict,
  217. needed_rois_dict,
  218. class_id_map):
  219. """
  220. 设置所需的gt格式,返回需要的json格式
  221. 适用于: 乳腺检测,肝脏局灶性疾病检测
  222. :param label_info:平台提供的label_info标注格式
  223. :param needed_imageresults_dict: 图像标签
  224. :param needed_rois_dict: roi标签
  225. :param class_id_map: 用于label改变的dict
  226. :return: 返回gt的json格式文件
  227. output_info = {'Label': 0, 'Confidence': 1.0, 'BoundingBox':[0, 0, 0, 0]}
  228. output_info = {'Label': 1, 'Confidence': 1.0, 'BoundingBox':[2, 3, 4, 5]}
  229. BoundingBox格式:left,top,right,bottom
  230. """
  231. labeled_result = label_info[0]["FileResultInfos"][0]["LabeledResult"]
  232. output_info_list = []
  233. output_label = []
  234. for each_roi_label in labeled_result["Rois"]:
  235. roi_cls = each_roi_label["Conclusion"]["Title"]
  236. if roi_cls in needed_rois_dict.keys():
  237. roi_points = each_roi_label["Points"]
  238. x, y = [], []
  239. for point in roi_points:
  240. x.append(int(point["X"]))
  241. y.append(int(point["Y"]))
  242. left, right = min(x), max(x)
  243. top, bottom = min(y), max(y)
  244. roi_boundingbox = [left, top, right, bottom]
  245. output_info = {'Label': class_id_map[needed_rois_dict[roi_cls]],
  246. 'Confidence': 1.0,
  247. 'BoundingBox': roi_boundingbox}
  248. output_info_list.append(output_info)
  249. if roi_cls == "肝脏未见明显异常":
  250. output_label.append(-1)
  251. else:
  252. output_label.append(class_id_map[needed_rois_dict[roi_cls]])
  253. if len(output_info_list) > 1:
  254. if (-1 in output_label) and (np.array(output_label) > 0).any():
  255. print('label_info为:{} 的图像,既标注了未见明显异常,又标注了弥漫性疾病,该图像作废'.format(label_info))
  256. return json.dumps([], ensure_ascii=False)
  257. elif (np.array(output_label) <= 0).all():
  258. return json.dumps([{'Label': 0, 'Confidence': 1.0, 'BoundingBox': [0, 0, 0, 0]}], ensure_ascii=False)
  259. else:
  260. output_info_list_new = []
  261. for i in range(len(output_info_list)):
  262. if output_info_list[i]['Label'] != 0:
  263. output_info_list_new.append(output_info_list[i])
  264. return json.dumps(output_info_list_new, ensure_ascii=False)
  265. elif len(output_info_list) == 1:
  266. if output_info_list[0]['Label'] == 0:
  267. return json.dumps([{'Label': 0, 'Confidence': 1.0, 'BoundingBox': [0, 0, 0, 0]}], ensure_ascii=False)
  268. else:
  269. return json.dumps(output_info_list, ensure_ascii=False)
  270. else:
  271. print('label_info为:{} 的图像,无法匹配任何所需的imageresults和rois的title,该图像作废'.format(label_info))
  272. return json.dumps(output_info_list, ensure_ascii=False)
  273. def gtfilegenerate_semantic_segmentation(label_info,
  274. image_size,
  275. needed_imageresults_dict,
  276. needed_rois_dict,
  277. class_id_map):
  278. """
  279. 设置所需的gt格式,返回需要的json格式
  280. 适用于: 语义分割
  281. :param label_info:
  282. :param needed_imageresults_dict:
  283. :param needed_rois_dict:
  284. :param class_id_map: 用于label改变的dict
  285. :return:
  286. output_info = {'Label': 0, 'Image_size':[20, 50], 'Confidence': 1.0, 'Contours':[]}
  287. output_info = {'Label': 0, 'Image_size':[20, 50], 'Confidence': 1.0, 'Contours':[ [ [1,2],[3,4] ] ]}
  288. """
  289. labeled_result = label_info[0]["FileResultInfos"][0]["LabeledResult"]
  290. output_info_list = []
  291. for image_result in labeled_result["ImageResults"]:
  292. image_cls = image_result["Conclusion"]["Title"]
  293. if image_cls in needed_imageresults_dict.keys():
  294. output_info = {'Label': class_id_map[needed_imageresults_dict[image_cls]], 'Image_size': image_size,
  295. 'Confidence': 1.0, 'Contours': []}
  296. output_info_list.append(output_info)
  297. for each_roi_label in labeled_result["Rois"]:
  298. roi_cls = each_roi_label["Conclusion"]["Title"]
  299. if roi_cls in needed_rois_dict.keys():
  300. roi_points = each_roi_label["Points"]
  301. roi_contour = []
  302. for point in roi_points:
  303. roi_contour.append([int(point["X"]), int(point["Y"])])
  304. output_info = {'Label': 0,
  305. 'Image_size': image_size,
  306. 'Confidence': 1.0,
  307. 'Contours': []}
  308. output_info['Label'] = class_id_map[needed_rois_dict[roi_cls]]
  309. output_info['Contours'].append(roi_contour)
  310. output_info_list.append(output_info)
  311. # 保证输出的output_info_list
  312. if len(output_info_list) == 0:
  313. print('label_info为:{} 的图像,无法匹配任何所需的imageresults和rois的title,该图像作废'.format(label_info))
  314. return json.dumps([], ensure_ascii=False)
  315. else:
  316. return json.dumps(output_info_list, ensure_ascii=False)
  317. def gtfilegenerate_semantic_segmentation_liverfocalSeg(label_info,
  318. image_size,
  319. needed_imageresults_dict,
  320. needed_rois_dict,
  321. class_id_map):
  322. """
  323. 设置所需的gt格式,返回需要的json格式
  324. :param label_info:平台提供的label_info标注格式
  325. :param needed_imageresults_dict: 图像标签
  326. :param needed_rois_dict: roi标签
  327. :param class_id_map: 用于label改变的dict
  328. :return: 返回gt的json格式文件
  329. output_info = {'Label': 0, 'Confidence': 1.0, 'BoundingBox':[0, 0, 0, 0]}
  330. output_info = {'Label': 1, 'Confidence': 1.0, 'BoundingBox':[2, 3, 4, 5]}
  331. BoundingBox格式:left,top,right,bottom
  332. """
  333. labeled_result = label_info[0]["FileResultInfos"][0]["LabeledResult"]
  334. output_info_list = []
  335. output_label = []
  336. for each_roi_label in labeled_result["Rois"]:
  337. roi_cls = each_roi_label["Conclusion"]["Title"]
  338. if roi_cls in needed_rois_dict.keys():
  339. roi_points = each_roi_label["Points"]
  340. roi_contour = []
  341. for point in roi_points:
  342. roi_contour.append([int(point["X"]), int(point["Y"])])
  343. output_info = {'Label': class_id_map[needed_rois_dict[roi_cls]],
  344. 'Image_size': image_size,
  345. 'Confidence': 1.0,
  346. 'Contours': []}
  347. output_info['Contours'].append(roi_contour)
  348. output_info_list.append(output_info)
  349. if roi_cls == "肝脏未见明显异常":
  350. output_label.append(-1)
  351. else:
  352. output_label.append(class_id_map[needed_rois_dict[roi_cls]])
  353. if len(output_info_list) > 1:
  354. if (-1 in output_label) and (np.array(output_label) > 0).any():
  355. print('label_info为:{} 的图像,既标注了未见明显异常,又标注了弥漫性疾病,该图像作废'.format(label_info))
  356. return json.dumps([], ensure_ascii=False)
  357. elif (np.array(output_label) <= 0).all():
  358. return json.dumps([{'Label': 0, 'Image_size': image_size, 'Confidence': 1.0, 'Contours': []}],
  359. ensure_ascii=False)
  360. else:
  361. output_info_list_new = []
  362. for i in range(len(output_info_list)):
  363. if output_info_list[i]['Label'] != 0:
  364. output_info_list_new.append(output_info_list[i])
  365. return json.dumps(output_info_list_new, ensure_ascii=False)
  366. elif len(output_info_list) == 1:
  367. if output_info_list[0]['Label'] == 0:
  368. return json.dumps([{'Label': 0, 'Image_size': image_size, 'Confidence': 1.0, 'Contours': []}],
  369. ensure_ascii=False)
  370. else:
  371. return json.dumps(output_info_list, ensure_ascii=False)
  372. else:
  373. print('label_info为:{} 的图像,无法匹配任何所需的imageresults和rois的title,该图像作废'.format(label_info))
  374. return json.dumps(output_info_list, ensure_ascii=False)
  375. def gtfilegenerate_semantic_segmentation_myocardial(label_info,
  376. image_size,
  377. needed_imageresults_dict,
  378. needed_rois_dict,
  379. class_id_map):
  380. """
  381. 设置所需的gt格式,返回需要的json格式
  382. 适用于: 心肌的语义分割
  383. 一般的语义分割中,如果有多个相同title的roi标签,则算多个病灶或者部位
  384. 心肌出现的情况是:只有两种情况:存在两个相同title的roi标签,是环形心肌(此时需要将两个轮廓放在一起);一个title的roi标签,是u型心肌
  385. :param label_info:
  386. :param needed_imageresults_dict:
  387. :param needed_rois_dict:
  388. :param class_id_map: 用于label改变的dict
  389. :return:
  390. output_info = {'Label': 0, 'Image_size':[20, 50], 'Confidence': 1.0, 'Contours':[]}
  391. output_info = {'Label': 0, 'Image_size':[20, 50], 'Confidence': 1.0, 'Contours':[ [ [1,2],[3,4] ] ]}
  392. output_info = {'Label': 0, 'Image_size':[20, 50], 'Confidence': 1.0, 'Contours':[ [ [1,2],[3,4] ] , [ [5,6],[7,8] ] ]}
  393. """
  394. labeled_result = label_info[0]["FileResultInfos"][0]["LabeledResult"]
  395. output_info_list = []
  396. # 图像标签判断
  397. for image_result in labeled_result["ImageResults"]:
  398. image_roi = image_result["Conclusion"]["Title"]
  399. if image_roi in needed_imageresults_dict.keys():
  400. output_info = {'Label': class_id_map[needed_imageresults_dict[image_roi]],
  401. 'Image_size': image_size,
  402. 'Confidence': 1.0,
  403. 'Contours': []}
  404. output_info_list.append(output_info)
  405. for each_roi_label in labeled_result["Rois"]:
  406. roi_cls = each_roi_label["Conclusion"]["Title"]
  407. if roi_cls in needed_rois_dict.keys():
  408. roi_points = each_roi_label["Points"]
  409. roi_contour = []
  410. for point in roi_points:
  411. roi_contour.append([int(point["X"]), int(point["y"])])
  412. output_info = {'Label': class_id_map[needed_rois_dict[roi_cls]],
  413. 'Image_size': image_size,
  414. 'Confidence': 1.0,
  415. 'Contours': []}
  416. output_info['Contours'].append(roi_contour)
  417. output_info_list.append(output_info)
  418. if len(output_info_list) == 2:
  419. if output_info_list[0]['Label'] == output_info_list[1]['Label']:
  420. output_info_list[0]['Contours'].append(output_info_list[1]['Contours'][0])
  421. output_info_list.pop(1)
  422. else:
  423. print('label_info为:{} 的图像,匹配两个不同title的rois标签,该图像作废'.format(label_info))
  424. return json.dumps([], ensure_ascii=False)
  425. if len(output_info_list) >= 3:
  426. print('label_info为:{} 的图像,匹配三个以上所需的imageresults和rois的title,该图像作废'.format(label_info))
  427. return json.dumps([], ensure_ascii=False)
  428. elif len(output_info_list) == 0:
  429. print('label_info为:{} 的图像,无法匹配任何所需的imageresults和rois的title,该图像作废'.format(label_info))
  430. return json.dumps([], ensure_ascii=False)
  431. else:
  432. return json.dumps(output_info_list, ensure_ascii=False)