1. # @Time : 2019.10.18
    2. # @Author : Bohrium.Kwong
    3. # @Licence : bio-totem
    4. import os
    5. import shutil
    6. import lxml.etree as ET
    7. from PIL import ImageDraw, Image
    8. import numpy as np
    9. import copy
    10. import cv2
    11. import glob
    12. import openslide_utils
    13. import sys
    14. sys.path.append('../')
    15. from openslide_utils import Slide
    16. # from xml_generate import get_contours
    17. import matplotlib.pyplot as plt
    18. current_path = os.path.dirname(__file__)
    19. def dist(a, b):
    20. return round(abs(a[0]-b[0]) + abs(a[1]-b[1]))
    21. def floatrange(start,end,step):
    22. floatrange_list = []
    23. for i in range(int((end-start)/step)):
    24. floatrange_list.append(round(start+step*i,1))
    25. return floatrange_list
    26. # xml_ori_path = 'where xml files save'
    27. def xml_change_color(xml_ori_path):
    28. for xml in glob.glob(xml_ori_path+'/*.xml*'):
    29. #print(xml)
    30. tree = ET.parse(xml)
    31. for a in tree.findall('.//Annotation'):
    32. # print(a.attrib['LineColor'])
    33. a.attrib['LineColor'] = '65535'
    34. tree.write(xml,pretty_print=True)
    35. ##解析xml文件获得坐标点
    36. def xml_to_region(xml_file):
    37. """
    38. parse XML label file and get the points
    39. :param xml_file: xml file
    40. :return: region list,region_class
    41. """
    42. tree = ET.parse(xml_file)
    43. region_list = []
    44. region_class = []
    45. for color in tree.findall('.//Annotation'):
    46. if color.attrib['LineColor'] in ['65280']: #zheli shi biaoqian zhong de biaozhu xian tiao de yanse,'65280'
    47. # '65280'是绿色,'255'是红色,可以根据自己的实际情况更改这个判断条件(或者直接if True)
    48. for region in color.findall('./Regions/Region'):
    49. vertex_list = []
    50. #region.attrib.get('Type')=='0':
    51. region_class.append(region.attrib.get('Type')) #region_class:leibie dui ying de suo yin
    52. for vertex in region.findall('.//Vertices/Vertex'):
    53. # parse the 'X' and 'Y' for the vertex
    54. vertex_list.append(vertex.attrib)
    55. region_list.append(vertex_list)
    56. return region_list,region_class
    57. ##解析xml文件获得坐标点
    58. def xml_to_region_pred(xml_file):
    59. """
    60. parse XML label file and get the points
    61. :param xml_file: xml file
    62. :return: region list,region_class
    63. """
    64. tree = ET.parse(xml_file)
    65. region_list = []
    66. region_class = []
    67. for color in tree.findall('.//Annotation'):
    68. if color.attrib['LineColor'] in ['255']: #zheli shi biaoqian zhong de biaozhu xian tiao de yanse,'65280'
    69. # '65280'是绿色,'255'是红色,可以根据自己的实际情况更改这个判断条件(或者直接if True)
    70. for region in color.findall('./Regions/Region'):
    71. vertex_list = []
    72. #region.attrib.get('Type')=='0':
    73. region_class.append(region.attrib.get('Type')) #region_class:leibie dui ying de suo yin
    74. for vertex in region.findall('.//Vertices/Vertex'):
    75. # parse the 'X' and 'Y' for the vertex
    76. vertex_list.append(vertex.attrib)
    77. region_list.append(vertex_list)
    78. return region_list,region_class
    79. ##将标签点(离散)加工成连续点,并将其绘制到原图上
    80. def region_handler(im, region_list,region_class, level_downsample):
    81. """
    82. handle region label point to discrete point, and draw the region point to line
    83. :param im: the image painted in region line
    84. :param region_list: region list, region point,
    85. eg : [[{'X': '27381.168113', 'Y': '37358.653791'}], [{'X': '27381.168113', 'Y': '37358.653791'}]]
    86. :param region_class : list,keep the value of region.attrib.get('Type') in elements of region list
    87. eg : [0,0,0,1,2,3]
    88. :param level_downsample: slide level down sample
    89. :return: image painted in region line of numpy array format
    90. """
    91. dr = ImageDraw.Draw(im)
    92. for r_class, region in enumerate(region_list):
    93. point_list = []
    94. if region_class[r_class] == '0' or region_class[r_class] == '3':
    95. for __, point in enumerate(region):
    96. X, Y = int(float(point['X'])/level_downsample), int(float(point['Y'])/level_downsample)
    97. point_list.append((X, Y))
    98. # points_length = len(point_list)
    99. x_max = max(point_list, key=lambda point: point[0])[0]
    100. x_min = min(point_list, key=lambda point: point[0])[0]
    101. y_max = max(point_list, key=lambda point: point[1])[1]
    102. y_min = min(point_list, key=lambda point: point[1])[1]
    103. # mislabeled, here checked by x and y coordinate max and min difference
    104. if (x_max - x_min < 50) or (y_max - y_min < 50): continue
    105. if region_class[r_class] == '3':
    106. dr.arc(point_list, 0, 360, fill='#00FF00', width=10) ##huizhi de yanse
    107. else:
    108. dr.line(point_list, fill="#00FF00", width=10) ##huizhi de yanse
    109. return im
    110. ##zhe shi wei le zai yuantu shang tongshi shengcheng biaoqian he yuce xiantiao shiyong de(fei bi xu)
    111. def region_handler_pred(im, region_list, region_class, level_downsample):
    112. """
    113. handle region label point to discrete point, and draw the region point to line
    114. :param im: the image painted in region line
    115. :param region_list: region list, region point,
    116. eg : [[{'X': '27381.168113', 'Y': '37358.653791'}], [{'X': '27381.168113', 'Y': '37358.653791'}]]
    117. :param region_class : list,keep the value of region.attrib.get('Type') in elements of region list
    118. eg : [0,0,0,1,2,3]
    119. :param level_downsample: slide level down sample
    120. :return: image painted in region line of numpy array format
    121. """
    122. dr = ImageDraw.Draw(im)
    123. for r_class, region in enumerate(region_list):
    124. point_list = []
    125. if region_class[r_class] == '0' or region_class[r_class] == '3':
    126. for __, point in enumerate(region):
    127. X, Y = int(float(point['X']) / level_downsample), int(float(point['Y']) / level_downsample)
    128. point_list.append((X, Y))
    129. # points_length = len(point_list)
    130. x_max = max(point_list, key=lambda point: point[0])[0]
    131. x_min = min(point_list, key=lambda point: point[0])[0]
    132. y_max = max(point_list, key=lambda point: point[1])[1]
    133. y_min = min(point_list, key=lambda point: point[1])[1]
    134. # mislabeled, here checked by x and y coordinate max and min difference
    135. if (x_max - x_min < 50) or (y_max - y_min < 50): continue
    136. if region_class[r_class] == '3':
    137. dr.arc(point_list, 0, 360, fill='#0000FF', width=0) ##huizhi de yanse
    138. else:
    139. dr.line(point_list, fill="#0000FF", width=10) ##huizhi de yanse
    140. return im
    141. def region_binary_image(tile, region_list, region_class, level_downsample):
    142. """
    143. convert the region labeled or not by doctor to binary image
    144. :param tile: a return image based on the method of Slide class object in 'utils.openslide_utils'
    145. :param region_list: region list, region point,
    146. eg : [[{'X': '27381.168113', 'Y': '37358.653791'}], [{'X': '27381.168113', 'Y': '37358.653791'}]]
    147. :param region_class : list,keep the value of region.attrib.get('Type') in elements of region list
    148. eg : [0,0,0,1,2,3]
    149. :param level_downsample: slide level down sample
    150. :return: image painted in region line of numpy array format
    151. """
    152. im = Image.new(mode="1", size=tile.size)
    153. dr = ImageDraw.Draw(im)
    154. regions_list = []
    155. for r_class, region in enumerate(region_list):
    156. point_list = []
    157. if region_class[r_class] == '0':
    158. for __, point in enumerate(region):
    159. X, Y = int(float(point['X']) / level_downsample), int(float(point['Y']) / level_downsample)
    160. point_list.append((X, Y))
    161. regions_list.append(point_list)
    162. # 由于医生的标注会出现不连续(非闭合)的情况,导致提取出来的标注坐标列表,会分成多段,比如:
    163. # 0 (1979, 798) (2144, 1479)
    164. # 1 (2139, 1483) (2319, 2162)
    165. # 2 (2308, 2160) (3003, 1646)
    166. # 正常情况下,标注坐标列表应该收尾闭合(前后坐标一致),上下列表之间差异应该较大,如:
    167. # 12 (1177, 2986) (1177, 2986)
    168. # 13 (1507, 2942) (1507, 2940)
    169. # 针对上述第一种情况,需要对提出出来的标注坐标列表进行循环判断,对收尾不一而且和其他标注列表的首坐标相对较近的话,进行合并处理
    170. pin_jie_flag = [] # 存储已经被拼接过的标注坐标列表序号
    171. single_list = [] # 存储新标注坐标列表的列表
    172. for j, p_list in enumerate(regions_list):
    173. if dist(p_list[0], p_list[-1]) < 50 and j not in pin_jie_flag:
    174. # 如果收尾坐标距离相差在150范围内(曼哈顿距离),且未成被拼接过,直接认为这个组坐标无须拼接,存储起来
    175. single_list.append(p_list)
    176. elif dist(p_list[0], p_list[-1]) > 50 and j not in pin_jie_flag:
    177. # 如果收尾坐标距离相差在150范围外(曼哈顿距离),且未成被拼接过,说明这组坐标是残缺非闭合的,需要对其余标注坐标进行新一轮的循环判断
    178. for j_2, p_list_2 in enumerate(regions_list):
    179. if j_2 != j and j_2 not in pin_jie_flag:
    180. if dist(p_list[-1], p_list_2[0]) < 50:
    181. p_list = p_list + p_list_2.copy()
    182. pin_jie_flag.append(j_2)
    183. elif dist(p_list[0], p_list_2[-1]) < 50:
    184. p_list = p_list_2.copy() + p_list
    185. pin_jie_flag.append(j_2)
    186. elif dist(p_list[-1], p_list_2[-1]) < 50:
    187. p_list_2_new = copy.deepcopy(p_list_2)
    188. p_list_2_new.reverse()
    189. p_list = p_list + p_list_2_new
    190. pin_jie_flag.append(j_2)
    191. elif dist(p_list[0], p_list_2[0]) < 50:
    192. p_list_2_new = copy.deepcopy(p_list_2)
    193. p_list_2_new.reverse()
    194. p_list = p_list_2_new + p_list
    195. pin_jie_flag.append(j_2)
    196. # 当这组非闭合的尾坐标和其他组坐标的首坐标接近到一定范围时(距离是150内),就让当前的非闭合的坐标列表和该组坐标列表相加
    197. # 处理完毕之后,将该组坐标的序号增加到已拼接坐标的列表中,确保后续循环不会再判断这个列表
    198. single_list.append(p_list)
    199. for points in single_list:
    200. dr.polygon(points, fill="#ffffff")
    201. # 由于医生的标注除了出现不连续(非闭合)的情况外,还存在多余勾画的情况,对这种情况暂时没有完整的思路予以接近,先用
    202. # opencv中的开闭操作组合来进行修补
    203. # kernel size depends on slide size,original is (20,20)
    204. kernel = np.ones((3, 3), np.uint8)
    205. filter_matrix = np.array(im).astype(np.uint8)
    206. filter_matrix = cv2.morphologyEx(filter_matrix, cv2.MORPH_OPEN, kernel)
    207. filter_matrix = cv2.morphologyEx(filter_matrix, cv2.MORPH_CLOSE, kernel)
    208. # plt.imshow(filter_matrix)
    209. return filter_matrix
    210. def change_xml_line_color(xml_ori_path):
    211. for xml in glob.glob(xml_ori_path+'/*.xml*'):
    212. #print(xml)
    213. tree = ET.parse(xml)
    214. for a in tree.findall('.//Annotation'):
    215. # print(a.attrib['LineColor'])
    216. a.attrib['LineColor'] = '65535'
    217. tree.write(xml,pretty_print=True)
    218. def save_label_and_pred_pic(svs_path,model_mode,xml_path_label,xml_path_pred,img_name,threshold=0):
    219. slide = Slide(svs_path)
    220. tile = slide.get_thumb() # 获取2级采样下的全片截图
    221. tile_copy = tile.copy()
    222. assert os.path.split(xml_path_label)[-1] == os.path.split(xml_path_pred)[-1]
    223. region_list_label,region_class_label = xml_to_region(xml_path_label)
    224. region_list_pred, region_class_pred = xml_to_region_pred(xml_path_pred)
    225. # #在这里使用xml_utils的方法进行指定区域提取(最终返回的是个True False矩阵)
    226. #region_process_mask = region_binary_image(tile, region_list_label, region_class_label,slide.get_level_downsample())
    227. # # 根据上述返回的标注坐标列表生成WSI原图2级采样大小的True False矩阵
    228. ##zhuyi: zheli shi like huizhi shangqu ,suoyi yao yong yici zhu shi yici
    229. region_xml_label_draw = region_handler(tile, region_list_label, region_class_label,slide.get_level_downsample())
    230. # sheng cheng label huizhi de tu
    231. plt.figure(figsize=(12.4,9.6))
    232. plt.imshow(region_xml_label_draw)
    233. plt.axis('off')
    234. plt.margins(0, 0)
    235. # plt.savefig(r'/media/totem_disk/totem/guozunhu/Project/(wen tai)projectC_cc/backup/(ds:12\18\24)/MainNet10/min_loss_model/paip/train/validation_in_train/label_pic/{}_{}_label_green.png'.format(img_name,model_mode))
    236. plt.savefig('/media/totem_disk/totem/guozunhu/Project/new_hooknet/test_ndpi_out_he_hn_cc_ce_train/ori_label/{}'.format(img_name))
    237. plt.close()
    238. # region_xml_pred_draw = region_handler_pred(tile_copy, region_list_pred, region_class_pred,slide.get_level_downsample())
    239. # #sheng cheng pred huizhi de tu
    240. # plt.imshow(region_xml_pred_draw)
    241. # plt.axis('off')
    242. # plt.margins(0, 0)
    243. # # plt.savefig(r'/media/totem_disk/totem/guozunhu/Project/(wen tai)projectC_cc/backup/ds:4\8\12/MainNet10/min_loss/epoch:600/pred_pic/label_and_pred/{}_{}.png'.format(img_name, model_mode))
    244. # # if not os.path.exists(r':600/validation_set/first_12_next_4/pred_xml_and_mask/arclength<800/{}/prec_pic'.format(threshold)):
    245. # # os.makedirs(r'/media/totem_disk/totem/guozunhu/Project/(wen tai)projectC_cc/backup/ds:4\8\12/MainNet10/halfway_hardsample/min_loss/epoch:600/validation_set/first_12_next_4/pred_xml_and_mask/arclength<800/{}/prec_pic'.format(threshold), exist_ok=True)
    246. # plt.savefig('/media/totem_disk/totem/guozunhu/Project/lp/test_ndpi_out_he_cc/{}_pred'.format(img_name))
    247. # plt.close()
    248. # region_xml_pred_draw = region_handler_pred(tile, region_list_pred, region_class_pred,slide.get_level_downsample())
    249. # #sheng cheng pred huizhi de tu
    250. # plt.imshow(region_xml_pred_draw)
    251. #
    252. # plt.axis('off')
    253. # plt.margins(0, 0)
    254. # plt.savefig('/media/totem_disk/totem/guozunhu/Project/lp/cache_ndpi_he_cc/hard_sample/ori_xml+hard_sample/pic/{}.png'.format(img_name))
    255. # plt.close()
    256. class Region:
    257. """"
    258. handle the template xml format file to insert label svs region
    259. """
    260. def __init__(self, xml_file):
    261. parser = ET.XMLParser(remove_blank_text=True)
    262. if not os.path.isfile(xml_file):
    263. template = os.path.join(current_path, "template.xml")
    264. shutil.copy(template, xml_file)
    265. self._xml_file = xml_file
    266. self._tree = ET.parse(xml_file, parser)
    267. def get_region(self, region_id):
    268. """
    269. get region by region id
    270. :param region_id: region id, 0: green, 1: yellow, 2: red, see the template.xml
    271. :return: the region
    272. """
    273. return self._tree.findall(".//Annotation/Regions")[region_id]
    274. def add(self, region_id, points):
    275. """
    276. add one region to the specified region by region id, the added region is ellipse
    277. and the parameter points is a rectangle bounded by an ellipse
    278. :param points: list with two element(upper-left, bottom-right), is the rectangle bounded by an ellipse
    279. :return:
    280. """
    281. region = self.get_region(region_id)
    282. region_num = len(region.findall(".//Region"))
    283. region_attr = {
    284. "Id": str(region_num+1),
    285. "Type": "2",
    286. "Zoom": "1",
    287. "Selected": "1",
    288. "ImageLocation": "",
    289. "ImageFocus": "0",
    290. "Length": "80",
    291. "Area": "400",
    292. "LengthMicrons": "20",
    293. "AreaMicrons": "30",
    294. "Text": "",
    295. "NegativeROA": "0",
    296. "InputRegionId": "0",
    297. "Analyze": "0",
    298. "DisplayId": "1"
    299. }
    300. region_tag = ET.Element("Region", region_attr)
    301. region.append(region_tag)
    302. attributes = ET.SubElement(region_tag, "Attributes")
    303. vertices = ET.Element("Vertices")
    304. region_tag.append(vertices)
    305. for point in points:
    306. # insert point
    307. ET.SubElement(vertices, "Vertex", attrib=point)
    308. def save(self):
    309. """
    310. save the xml file
    311. :return:
    312. """
    313. self._tree.write(self._xml_file, pretty_print=True)
    314. if __name__ == '__main__':
    315. if False:
    316. model_mode = 'min_loss'
    317. assert model_mode in ['min_loss','best_f1','last']
    318. svs_path_root = '/media/totem_disk/totem/guozunhu/Project/new_hooknet/data_cc/valid'
    319. svs_path_list = glob.glob(svs_path_root+'/*.svs')
    320. # svs_path_list = sorted(glob.glob(svs_path_root+'/*.svs'))
    321. xml_path_label_root = r'/media/totem_disk/totem/guozunhu/Project/new_hooknet/data_cc/valid'
    322. xml_path_pred_root = r'/media/totem_disk/totem/guozunhu/Project/new_hooknet/data_cc/valid'
    323. for svs_path in svs_path_list:
    324. # xml_path_label = '/media/totem_disk/totem/guozunhu/Project/lp/cache_ndpi_he_cc/hard_sample/ori_xml+hard_sample'
    325. # xml_path_pred = '/media/totem_disk/totem/guozunhu/Project/lp/cache_ndpi_he_cc/hard_sample/ori_xml+hard_sample'
    326. img_name = os.path.split(svs_path)[-1].split('.svs')[0]
    327. # if 'neg' in img_name:
    328. # continue
    329. xml_path_label = glob.glob(xml_path_label_root+'/*{}.xml'.format(img_name))[0]
    330. xml_path_pred = glob.glob(xml_path_pred_root+'/*{}.xml'.format(img_name))[0]
    331. assert os.path.split(xml_path_label)[-1] == os.path.split(xml_path_pred)[-1]
    332. save_label_and_pred_pic(svs_path,model_mode,xml_path_label,xml_path_pred,img_name)
    333. print("Finished:{}".format(os.path.split(svs_path)[-1]))
    334. if True:
    335. import yaml
    336. model_mode = 'min_loss'
    337. for i in range(0,10):
    338. th = i / 10
    339. mean_dice = {'mean_dice':0}
    340. low_dice_list = []
    341. all_img_path = glob.glob('/media/totem_disk/totem/guozunhu/Project/new_hooknet/test_ndpi_out_he_hn_cc_ce_train/ds:12 20_new_dataset/merge_mask/{}/*.png'.format(th))
    342. for img_path in all_img_path:
    343. img_name = os.path.splitext(img_path)[0].split('/')[-1]
    344. # svs_path = '/media/totem_disk/totem/guozunhu/Project/lp/all_svs/first_batch/all/{}.svs'.format(img_name)
    345. # xml_path_label = '/media/totem_disk/totem/guozunhu/Project/lp/all_svs/first_batch/all/{}.xml'.format(img_name)
    346. # region_list, region_class = xml_to_region(xml_path_label)
    347. # slide = Slide(svs_path)
    348. # tile = slide.get_thumb()
    349. # level_downsample = slide.get_level_downsample()
    350. # label = region_binary_image(tile,region_list,region_class,level_downsample)
    351. # label = np.where(label < 0.5, 0, label)
    352. # label = np.where(label >= 0.5, 1, label)
    353. # cv2.imwrite('/media/totem_disk/totem/guozunhu/Project/lp_2/cache_ndpi_he_cc/hot_pic/true_mask/{}_label.png'.format(img_name),label*255)
    354. # print(img_name)
    355. if 'neg' in img_name:
    356. continue
    357. label = cv2.imread('/media/totem_disk/totem/guozunhu/Project/lp/backup/before/all/true_mask/{}_label.png'.format(img_name),0)
    358. label = np.where(label < 127.5, 0, label)
    359. label = np.where(label >= 127.5, 1, label)
    360. # todo:分别计算不同ds倍率下热图的dice
    361. all_ds = [2,4,6]
    362. for ds in all_ds:
    363. out = cv2.imread('/media/totem_disk/totem/guozunhu/Project/temp_3/cache_ndpi_he_cc/M10:4_8_12(最大像素值)/hot_pic/{}_{}.png'.format(img_name,ds),0)
    364. out_2 = out.copy()
    365. out_2 = np.where(out_2 < 128,0,out_2)
    366. out_2 = np.where(out_2 >= 128,1,out_2)
    367. tp = (out_2 * label).sum(dtype=np.int)
    368. fp = out_2.sum(dtype=np.int) - tp
    369. label_p_num = label.sum(dtype=np.int)
    370. dice = 2 * tp / (label_p_num + tp + fp + 1e-8)
    371. out = cv2.cvtColor(out, cv2.COLOR_GRAY2BGR)
    372. cv2.putText(out, 'dice:{}'.format(dice), (200, 600), cv2.FONT_HERSHEY_SIMPLEX, 20,(255, 255,255), 25, cv2.LINE_AA)
    373. cv2.imwrite('/media/totem_disk/totem/guozunhu/Project/temp_3/cache_ndpi_he_cc/M10:4_8_12(最大像素值)/hot_pic/dice/{}_{}.png'.format(img_name,ds),out)
    374. # todo:计算merge_mask de dice
    375. out = cv2.imread('/media/totem_disk/totem/guozunhu/Project/lp_3_u2net/predict/merge_mask/{}/{}.png'.format(th,img_name),0)
    376. out_2 = out.copy()
    377. out_2 = np.where(out_2 < 128,0,out_2)
    378. out_2 = np.where(out_2 >= 128,1,out_2)
    379. tp = (out_2 * label).sum(dtype=np.int)
    380. fp = out_2.sum(dtype=np.int) - tp
    381. label_p_num = label.sum(dtype=np.int)
    382. dice = 2 * tp / (label_p_num + tp + fp + 1e-8)
    383. # if dice < 0.7:
    384. # low_dice_list.append(img_name)
    385. # # mean_dice['mean_dice'] += (dice / len(all_img_path)).item()
    386. # mean_dice['mean_dice'] += (dice / 28).item()
    387. #
    388. # out = cv2.cvtColor(out, cv2.COLOR_GRAY2BGR)
    389. # cv2.putText(out, 'dice:{}'.format(dice), (200, 200), cv2.FONT_HERSHEY_SIMPLEX, 8,(255, 255,255), 10, cv2.LINE_AA)
    390. # save_root_path = '/media/totem_disk/totem/guozunhu/Project/lp_3_u2net/predict/dice' + '/' + str(th)
    391. # if not os.path.exists(save_root_path):
    392. # os.mkdir(save_root_path)
    393. # save_path = save_root_path + '/' + img_name + '.png'
    394. # cv2.imwrite(save_path,out)
    395. # mean_dice['low_dice_list'] = low_dice_list
    396. # yaml.safe_dump(mean_dice,open('/media/totem_disk/totem/guozunhu/Project/lp_3_u2net/predict/dice/{}/mean_dice.yml'.format(th),'w'))
    397. if False:
    398. import yaml
    399. mean_dice = {'mean_dice':0}
    400. low_dice_list = []
    401. all_img_path = glob.glob('/media/totem_disk/totem/guozunhu/Project/new_hooknet/test_ndpi_out_he_hn_cc_ce_train/ds:12 20_valid/*_hm_m.png')
    402. for img_path in all_img_path:
    403. img_name = os.path.splitext(img_path)[0].split('/')[-1].split('_hm_m')[0]
    404. # if 'neg' in img_name:
    405. # continue
    406. svs_path = '/media/totem_disk/totem/guozunhu/Project/new_hooknet/data_cc/valid/{}.svs'.format(img_name)
    407. xml_path_label = '/media/totem_disk/totem/guozunhu/Project/new_hooknet/data_cc/valid/{}.xml'.format(img_name)
    408. region_list, region_class = xml_to_region(xml_path_label)
    409. slide = Slide(svs_path)
    410. tile = slide.get_thumb()
    411. level_downsample = slide.get_level_downsample()
    412. label = region_binary_image(tile,region_list,region_class,level_downsample)
    413. label = np.where(label < 0.5, 0, label)
    414. label = np.where(label >= 0.5, 1, label)
    415. print(img_name)
    416. pred = cv2.imread(img_path,0)
    417. pred = cv2.resize(pred,(label.shape[1],label.shape[0]))
    418. pred = np.where(pred < 128,0,pred)
    419. pred = np.where(pred >= 128,1,pred)
    420. tp = (pred * label).sum(dtype=np.int)
    421. fp = pred.sum(dtype=np.int) - tp
    422. label_p_num = label.sum(dtype=np.int)
    423. dice = 2 * tp / (label_p_num + tp + fp + 1e-8)
    424. if dice < 0.9:
    425. low_dice_list.append(img_name)
    426. mean_dice['mean_dice'] += (dice / len(all_img_path)).item()
    427. mean_dice['low_dice_list'] = low_dice_list
    428. yaml.safe_dump(mean_dice,open('/media/totem_disk/totem/guozunhu/Project/new_hooknet/test_ndpi_out_he_hn_cc_ce_train/ds:12 20_valid/dice/mean_dice.yml','w'))
    429. # xml_path_label = '/media/totem_disk/totem/guozunhu/Project/cc/xml_check/cc/he/pred_xml/634671.xml'
    430. # region_list, region_class = xml_to_region(xml_path_label)
    431. # slide = Slide('/media/totem_disk/totem/guozunhu/Project/lp_3_u2net/backup/valid/634671.svs')
    432. # tile = slide.get_thumb()
    433. # level_downsample = slide.get_level_downsample()
    434. # label = region_binary_image(tile,region_list,region_class,level_downsample)
    435. # label = np.where(label < 0.5, 0, label)
    436. # label = np.where(label >= 0.5, 1, label)
    437. # cv2.imwrite('/media/totem_disk/totem/guozunhu/Project/cc/xml_check/cc/he/pred_xml/634671.png',label*255)
    438. # print(img_name)
    439. # if True:
    440. # cache_paths = glob.glob('/media/totem_disk/totem/guozunhu/Project/lp_4_hooknet/cache_ndpi_he_cc/*_cache')
    441. # for cache_path in cache_paths:
    442. # svs_name = os.path.splitext(cache_path)[0].split('/')[-1].split('_cache')[0]
    443. # svs_path = '/media/totem_disk/totem/Data_20201014/LABIAL_SALIVARY_GLAND_BIOPSY/{}.svs'.format(svs_name)
    444. # slide = Slide(svs_path)
    445. # tile = slide.get_thumb()
    446. # save_path = '/media/totem_disk/totem/guozunhu/Project/lp_4_hooknet/xml_out/ori/{}.png'.format(svs_name)
    447. # if os.path.exists(save_path):
    448. # continue
    449. # tile.save(save_path)
    450. # print(svs_name)