def upsample_crop_save_ct(self): """ for io of "out_hgh", upsample is not necessary. So we need an if/else. :return: """ masks = self.mask scan_file = self.file_name pad_nb = self.pad_nb if any(self.trgt_space_list) or any( self.trgt_sz_list): # only for lobe yet. print('start upsampling the output mask to original size/spacing') final_pred = downsample(masks, is_mask=True, ori_space=self.trgt_space_list, trgt_space=self.spacing, ori_sz=masks.shape, trgt_sz=self.original_shape, order=1, labels=self.labels) else: final_pred = masks print('final_pred.shape: ', final_pred.shape) mask = final_pred[pad_nb:-pad_nb, pad_nb:-pad_nb, pad_nb:-pad_nb] if not os.path.exists(self.preds_dir): os.makedirs(self.preds_dir) futil.save_itk(self.preds_dir + '/' + scan_file.split('/')[-1], mask, self.origin, self.spacing) print('successfully save ct mask at', self.preds_dir + '/' + scan_file.split('/')[-1])
def write_connected_lobe( mylock ): # neural network inference needs GPU which can not be computed by multi threads, so the # consumer is just the upsampling only. while True: with mylock: ct_fpath = None if len( scan_files ): # if scan_files are empty, then threads should not wait any more print( threading.current_thread().name + " gets the lock, thread id: " + str(threading.get_ident()) + " prepare to compute largest 5 lobes , waiting for the data from queue" ) ct_fpath = scan_files.pop() # wait up to 1 minutes print(threading.current_thread().name + " gets the data, thread id: " + str(threading.get_ident()) + " prepare to release the lock.") if ct_fpath is not None: t1 = time.time() print(threading.current_thread().name + "is computing ...") pred, pred_origin, pred_spacing = futil.load_itk(ct_fpath) pred = largest_connected_parts(pred, nb_need_saved=5) suffex_len = len(os.path.basename(ct_fpath).split(".")[-1]) if target_dir: new_dir = target_dir else: new_dir = os.path.dirname(ct_fpath) + "/biggest_5_lobe" if not os.path.exists(new_dir): os.makedirs(new_dir) print('successfully create directory:', new_dir) write_fpath = new_dir + "/" + os.path.basename( ct_fpath)[:-suffex_len - 1] + '.mhd' futil.save_itk(write_fpath, pred, pred_origin, pred_spacing) t3 = time.time() print("successfully save largest 5 lobes at " + write_fpath) print( "it costs tis seconds to compute the largest 5 lobes of the data " + str(t3 - t1)) else: print(threading.current_thread().name + "scan_files are empty, finish the thread") return None
def write_all_metrics_for_one_ct(mylock, labels, gdth_name, pred_name, csv_file, lung, fissure): gdth, gdth_origin, gdth_spacing = futil.load_itk(gdth_name) pred, pred_origin, pred_spacing = futil.load_itk(pred_name) if lung: # gdth is lung, so pred need to convert to lung from lobes, labels need to be [1], # size need to be the same the the gdth size (LOLA11 mask resolutin is 1 mm, 1mm, 1mm) pred = get_lung_from_lobe(pred) labels = [1] if not gdth.shape == pred.shape: # sometimes the gdth size is different with preds. pred = downsample(pred, ori_sz=pred.shape, trgt_sz=gdth.shape, order=1, labels=labels) # use shape to upsampling because the space is errors sometimes in LOLA11 suffex_len = len(os.path.basename(pred_name).split(".")[-1]) lung_file_dir = os.path.dirname(pred_name) + "/lung" lung_file_fpath = lung_file_dir + "/" + os.path.basename(pred_name)[:-suffex_len-1] + '.mhd' if not os.path.exists(lung_file_dir): os.makedirs(lung_file_dir) futil.save_itk(lung_file_fpath, pred, pred_origin, pred_spacing) elif fissure and ('LOLA11' in gdth_name or "lola11" in gdth_name): # only have slices annotations pred_cp = copy.deepcopy(pred) slic_nb=0 for i in range(gdth.shape[1]): # gdth.shape=(600, 512, 512) gdth_slice = gdth[:, i, :] if not gdth_slice.any(): # the slice is all black pred_cp[:, i, :] = 0 else: slic_nb+=1 # print("gdth slice sum"+str(np.sum(gdth_slice))) for j in range(gdth.shape[2]): # some times only one lobe is annotated in the same slice. gdth_line = gdth_slice[:, j] if not gdth_line.any(): pred_cp[:, i, j] = 0 if slic_nb > 30: print('slice number of valuable lobe is greater than 30: '+str(slic_nb)+", change to another axis") pred_cp = copy.deepcopy(pred) slic_nb = 0 for i in range(gdth.shape[2]): # gdth.shape=(600, 512, 512) gdth_slice = gdth[:, :, i] if not gdth_slice.any(): # the slice is all black pred_cp[:, :, i] = 0 else: slic_nb += 1 # print("gdth slice sum" + str(np.sum(gdth_slice))) for j in range(gdth.shape[1]): # some times only one lobe is annotated in the same slice. gdth_line = gdth_slice[:, j] if not gdth_line.any(): pred_cp[:, j, i] = 0 if slic_nb > 30: raise Exception("cannot get fissure points") pred = pred_cp futil.save_itk(pred_name.split(".mh")[0]+"_points.mha", pred, pred_origin, pred_spacing) print('slice number of valuable lobe: ', slic_nb) gdth = one_hot_encode_3D(gdth, labels=labels) pred = one_hot_encode_3D(pred, labels=labels) print('start calculate all metrics for image: ', pred_name) metrics_dict_all_labels = get_metrics_dict_all_labels(labels, gdth, pred, spacing=pred_spacing[::-1]) metrics_dict_all_labels['filename'] = pred_name # add a new key to the metrics data_frame = pd.DataFrame(metrics_dict_all_labels) with mylock: data_frame.to_csv(csv_file, mode='a', header=not os.path.exists(csv_file), index=False) print(threading.current_thread().name + "successfully write metrics to csv " + csv_file)
#LOAD THE CT_SCAN scan_file = 'VESSEL12_15.mhd' ct_scan, origin, spacing, orientation = futil.load_itk('data/val/A/'+scan_file, get_orientation=True) if (orientation[-1] == -1): ct_scan = ct_scan[::-1] print 'Origem: ' print origin print 'Spacing: ' print spacing print 'Orientation: ' print orientation #NORMALIZATION ct_scan = futil.normalize(ct_scan) #PREDICT the segmentation t1 = time.time() lobe_mask = segment.predict(ct_scan) t2 = time.time() print t2-t1 #Save the segmentation futil.save_itk('results/'+scan_file, lobe_mask, origin, spacing)
def writeFissure(ctFpath, fissureFpath, radiusValue=3, Absdir=None): scan, origin, spacing = futil.load_itk(ctFpath) fissure = get_fissure(scan, radiusValue=radiusValue) futil.save_itk(fissureFpath, fissure, origin, spacing) print('save ct mask at', fissureFpath)
z_sz=64) #LOAD THE CT_SCAN scan_file = 'test.mhd' ct_scan, origin, spacing, orientation = futil.load_itk( "/content/LungLobeSegmentation/data/" + scan_file, get_orientation=True) if (orientation[-1] == -1): ct_scan = ct_scan[::-1] print 'Origem: ' print origin print 'Spacing: ' print spacing print 'Orientation: ' print orientation #NORMALIZATION ct_scan = futil.normalize(ct_scan) print 'succesfully normalized' #PREDICT the segmentation t1 = time.time() print 't1: ' print t1 lobe_mask = segment.predict(ct_scan) t2 = time.time() print t2 - t1 #Save the segmentation futil.save_itk('/content/LungLobeSegmentation/results/' + scan_file, lobe_mask, origin, spacing)
path_to_input_scan_file = 'data/006_ref_raw_f64.nii.gz' path_to_input_scan_file = 'data/003_GST_CTce_raw_crop.nii.gz' finally: assert os.path.isfile(path_to_input_scan_file), "ERROR no such input file as {}".format(path_to_input_scan_file) #LOAD THE CT_SCAN ct_scan, origin, shape, spacing, orientation = futil.load_itk(path_to_input_scan_file, get_orientation=True) if (orientation[-1] == -1): ct_scan = ct_scan[::-1] logger.info('origin: {} {} {}'.format(*origin)) logger.info('shape: {} {} {}'.format(*shape)) logger.info('spacing: {} {} {}'.format(*spacing)) logger.info('orientation: {} {} {} {} {} {} {} {} {}'.format(*orientation)) #NORMALIZATION ct_scan = futil.normalize(ct_scan) #PREDICT the segmentation t1 = time.time() lobe_mask = segment.predict(ct_scan) t2 = time.time() logger.info('prediction runtime (s): %i', int(t2-t1)) # map labels to innersight-os labels for p in [(4,25),(5,24),(6,23),(7,22),(8,21)]: lobe_mask[np.where(lobe_mask==p[0])]=p[1] #Save the segmentation path_to_output_scan_file = path_to_input_scan_file.replace('.nii', '_sumLobes.nii') futil.save_itk(path_to_output_scan_file, lobe_mask, origin, spacing)