def fileopen(): filename = filedialog.askopenfilename( filetypes=[('mhd files', '*.mhd'), ('dicom files', '*.dcm'), ('numpy files', '*.npy'), ('all', '*')]) #filename = "E:/tianchi_project/TIANCHI_examples/train_1/LKDS-00001.mhd" if filename == '': return print(repr(filename)) prename, extname = os.path.splitext(filename) if extname == '.mhd': full_image_info = sitk.ReadImage(filename) full_scan = sitk.GetArrayFromImage(full_image_info) old_spacing = np.array(full_image_info.GetSpacing())[::-1] volimg, new_spacing = mt.resample(full_scan, old_spacing) elif extname == '.dcm': pathname = os.path.split(filename)[0] full_scan, full_image_info, patientid = mt.read_dicom_scan( pathname) cvm.view_CT(full_scan) old_spacing = np.array(full_image_info.GetSpacing())[::-1] volimg, new_spacing = mt.resample(full_scan, old_spacing) elif extname == '.npy': volimg = np.load(filename) else: print('unknown data type') return label = tk.Label(tool_view, image=cvm.view_CT(volimg)) label.pack() tool_view.quit()
def annotations_crop(self, overbound=True, candsample=False): if os.access(self.output_path, os.F_OK): shutil.rmtree(self.output_path) os.makedirs(self.output_path) os.mkdir(self.nodules_npy_path) os.mkdir(self.nonnodule_npy_path) if not os.access(self.vision_path, os.F_OK): os.makedirs(self.vision_path) for patient in enumerate(tqdm(self.ls_all_patients[814:])): patient = patient[1] #patient = "./SLH_data/0721/285 0800418645" print(patient) full_scan, full_image_info, patient_uid = mt.read_dicom_scan( patient) if full_scan.min() < -1024: errorlog = open("results/error.log", "w") errorlog.write("Hu unit incorrect:%s\n" % (patient)) errorlog.close() origin = np.array( full_image_info.GetOrigin())[::-1] #---获取“体素空间”中结节中心的坐标 old_spacing = np.array(full_image_info.GetSpacing() )[::-1] #---该CT在“世界空间”中各个方向上相邻单位的体素的间距 min_space = old_spacing.min() image, new_spacing = mt.resample(full_scan, old_spacing) #---重采样 print('resample done') silist = self.df_annotations.serie_id.tolist() if silist.count(patient_uid) == 0: print('no annotation for this patient found') continue serie_index = silist.index(patient_uid) patient_nodules = [] for annocol in self.annotation_columns: annostr = self.df_annotations.get(annocol)[serie_index] if type(annostr) == unicode: #annotation = np.array(annostr.split(u'\uff08')[0].split(' '), dtype=int) #patient_nodules.append([serie_index, annotation]) #the index order is [x,y,z] if annostr.find(u'*') >= 0: continue coordbegin = -1 coordend = -1 for ci in range(len(annostr)): if coordbegin < 0: if annostr[ci] >= u'0' and annostr[ci] <= u'9': coordbegin = ci elif (annostr[ci] < u'0' or annostr[ci] > u'9') and annostr[ci] != u' ': coordend = ci break if coordbegin >= 0: if coordend < 0: coordend = len(annostr) coordstr = annostr[coordbegin:coordend] annotation = np.array(coordstr.split(u' '), dtype=int) patient_nodules.append( [annocol, annotation]) # the index order is [x,y,z] if type(annostr) == str: if annostr.find('*') >= 0: continue coordbegin = -1 coordend = -1 for ci in range(len(annostr)): if coordbegin < 0: if annostr[ci] >= '0' and annostr[ci] <= '9': coordbegin = ci elif (annostr[ci] < '0' or annostr[ci] > '9') and annostr[ci] != ' ': coordend = ci break if coordbegin >= 0: # annotation = np.array(annostr.split('(')[0].split(' '), dtype=int) if coordend < 0: coordend = len(annostr) coordstr = annostr[coordbegin:coordend] annotation = np.array(coordstr.split(' '), dtype=int) patient_nodules.append( [annocol, annotation]) # the index order is [x,y,z] v_centers = [] center_coords = [] for annocol, nodule in patient_nodules: nodule_center = np.array(np.flip(nodule, axis=0) * old_spacing / new_spacing, dtype=int) #---获取“世界空间”中结节中心的坐标 #v_center = np.rint((nodule_center - origin) / new_spacing) #映射到“体素空间”中的坐标 #v_center = np.array(v_center, dtype=int) v_centers.append([annocol, nodule_center]) center_coords.append(nodule_center) #volume_regioned = cv.view_coordinations(image, center_coords, window_size=10, reverse=False, slicewise=False, show=False) #cv.view_CT(volume_regioned) #np.save(self.vision_path+"/"+patient_uid+"_annotated.mhd", volume_regioned) #---这一系列的if语句是根据“判断一个结节的癌性与否需要结合该结节周边位置的阴影和位置信息”而来,故每个结节都获取了比该结节尺寸略大的3D体素 #get annotations nodule window_half = int(BOX_SIZE / 2) if overbound: box_size = 2 * BOX_SIZE box_half = BOX_SIZE else: box_size = BOX_SIZE box_half = window_half for annocol, v_center in v_centers: zyx_1 = v_center - box_half # 注意是: Z, Y, X zyx_2 = v_center + box_half if mt.coord_overflow(zyx_1, image.shape) or mt.coord_overflow( zyx_2, image.shape): zyx_1_fix = zyx_1.copy() zyx_2_fix = zyx_2.copy() for ci in range(3): if zyx_1[ci] < 0: zyx_1_fix[ci] = 0 elif zyx_1[ci] >= image.shape[ci]: zyx_1_fix[ci] = image.shape[ci] if zyx_2[ci] < 0: zyx_2_fix[ci] = 0 elif zyx_2[ci] >= image.shape[ci]: zyx_2_fix[ci] = image.shape[ci] img_crop = image[zyx_1_fix[0]:zyx_2_fix[0], zyx_1_fix[1]:zyx_2_fix[1], zyx_1_fix[2]:zyx_2_fix[2]] img_crop[img_crop < -1024] = -1024 #if img_crop.max() >= 600: # padding_value = 600 #elif img_crop.max() >= 0: # padding_value = img_crop.max() #else: # padding_value = -1024 padding_value = -1024 nodule_box = padding_value * np.ones( [box_size, box_size, box_size], int) nodule_box[zyx_1_fix[0] - zyx_1[0]:zyx_2_fix[0] - zyx_1[0], zyx_1_fix[1] - zyx_1[1]:zyx_2_fix[1] - zyx_1[1], zyx_1_fix[2] - zyx_1[2]:zyx_2_fix[2] - zyx_1[2]] = img_crop else: #nodule_box = np.zeros([box_size, box_size, box_size], np.int16) img_crop = image[zyx_1[0]:zyx_2[0], zyx_1[1]:zyx_2[1], zyx_1[2]:zyx_2[2]] # ---截取立方体 img_crop[img_crop < -1024] = -1024 # ---设置窗宽,小于-1024的体素值设置为-1024 nodule_box = img_crop[0:box_size, 0:box_size, 0:box_size] # ---将截取的立方体置于nodule_box self.save_annotations_nodule( nodule_box, patient_uid + "_" + annocol + "_ob") print("annotation sampling done") #get candidate annotation nodule candidate_coords = [] if candsample: segimage, segmask, flag = cd.segment_lung_mask(image) if segimage is not None: nodule_matrix, index = cd.candidate_detection( segimage, flag) cluster_labels = lc.seed_mask_cluster(nodule_matrix, cluster_size=1000) #cluster_labels = lc.seed_volume_cluster(image, segmask, eliminate_lower_size=-1) #segresult = lc.segment_color_vision(image, cluster_labels) #cv.view_CT(segresult) #lc.cluster_size_vision(cluster_labels) candidate_coords, _ = lc.cluster_centers(cluster_labels) #candidate_coords = lc.cluster_center_filter(image, candidate_coords) #the coordination order is [z,y,x] print("candidate number:%d" % (len(candidate_coords))) #volume_regioned = cv.view_coordinations(image, candidate_coords, window_size=10, reverse=False, slicewise=True, show=False) #mt.write_mhd_file(self.vision_path+"/"+patient_uid+"_candidate.mhd", volume_regioned, volume_regioned.shape[::-1]) for cc in range(len(candidate_coords)): candidate_center = candidate_coords[cc] invalid_loc = False if mt.coord_overflow(candidate_center - window_half, image.shape) or mt.coord_overflow( candidate_center + BOX_SIZE - window_half, image.shape): invalid_loc = True continue for index_search, v_center_search in v_centers: rpos = v_center_search - candidate_center if abs(rpos[0]) < window_half and abs( rpos[1] ) < window_half and abs( rpos[2] ) < window_half: #the negative sample is located in the positive location invalid_loc = True break if not invalid_loc: zyx_1 = candidate_center - window_half zyx_2 = candidate_center + BOX_SIZE - window_half nodule_box = np.zeros( [BOX_SIZE, BOX_SIZE, BOX_SIZE], np.int16) #---nodule_box_size = 45 img_crop = image[zyx_1[0]:zyx_2[0], zyx_1[1]:zyx_2[1], zyx_1[2]:zyx_2[2]] #---截取立方体 img_crop[img_crop < -1024] = -1024 #---设置窗宽,小于-1000的体素值设置为-1000 if img_crop.shape[0] != BOX_SIZE | img_crop.shape[ 1] != BOX_SIZE | img_crop.shape[2] != BOX_SIZE: print("error in resmapleing shape") try: nodule_box[ 0:BOX_SIZE, 0:BOX_SIZE, 0: BOX_SIZE] = img_crop # ---将截取的立方体置于nodule_box except: print("random error") continue #nodule_box[nodule_box == 0] = -1024#---将填充的0设置为-1000,可能有极少数的体素由0=>-1000,不过可以忽略不计 self.save_nonnodule(nodule_box, patient_uid + "_cc_" + str(cc)) print("candidate sampling done") print('Done for this patient!\n\n') print('Done for all!')
results = [] CPMs = [] CPMs2 = [] test_patients = all_patients bt.filelist_store(all_patients, evaluation_path + "/patientfilelist.log") #random.shuffle(test_patients) for p in range(len(test_patients)): result = [] patient = test_patients[p] #uid = mt.get_mhd_uid(patient) #annotations = mt.get_luna_annotations(uid, annotation_file) #if len(annotations)==0: #print('%d/%d patient %s has no annotations, ignore it.' %(p+1, len(test_patients), uid)) #continue full_scan, image_info = mt.read_dicom_scan(patient) uid = image_info['uid'] print('%d/%d processing patient:%s' % (p + 1, len(test_patients), uid)) origin = image_info['origin'] old_spacing = image_info['spacing'] image, new_spacing = mt.resample(full_scan, old_spacing) #resample print('Resample Done. time:{}s'.format(time.time() - start_time)) #make a real nodule visualization real_nodules = [] #for annotation in annotations: #real_nodule = np.int_([abs(annotation[2]-origin[0])/new_spacing[0], abs(annotation[1]-origin[1])/new_spacing[1], abs(annotation[0]-origin[2])/new_spacing[2]]) #real_nodules.append(real_nodule) if 'vision_path' in dir() and 'vision_path' is not None: annotation_vision = cvm.view_coordinates(image,