def _save_failed_qc_image(self, plot_title, mask): plt.imshow(mask) plt.title(plot_title) case_dir = check_directory( os.path.join(self.output_path, 'failed_qc', self.s_sopid.replace('.', '_'))) shutil.rmtree('{}/*'.format(case_dir), ignore_errors=True) failed_dir = check_directory( os.path.join(self.output_path, 'failed_qc', self.s_sopid.replace('.', '_'), str(self.cycle_index))) plt.savefig( os.path.join( failed_dir, '{}_{}_{}.png'.format(self.img_index, plot_title, self.cycle_index))) plt.close()
def _print_error_file_corrupted(self): print('Pickle file corrupted') filename = self.filename.split('.')[0] error_file_dir = check_directory( os.path.join(self.output_path, 'failed_qc', filename)) error_file = os.path.join(error_file_dir, '{}.txt'.format(filename)) txt_file = open(error_file, 'w') txt_file.write('File {} is corrupted'.format(filename)) txt_file.close()
def _print_error_file_pickle(self, cause): print('Pickle fields missing') error_filename = cause[0].split('.')[0] error_file_dir = check_directory( os.path.join(self.output_path, 'failed_qc', error_filename)) error_file = os.path.join(error_file_dir, '{}.txt'.format(error_filename)) txt_file = open(error_file, 'w+') txt_file.write( 'At least one of the relevant fields in the pickle {} is missing: {}' .format(cause[0], cause[1])) txt_file.close()
def _save_cycles(self, cycles, failed_frames=(None), resize=True, sequence='', subject='', kind='bsh_examples'): out_dir = check_directory(os.path.join(self.output_path, kind)) out_dir = check_directory(os.path.join(out_dir, '{}'.format(subject))) for ci, cycle in enumerate(cycles): print(ci) if len(cycle) == 1: print('Single image {}'.format(self.filename)) continue cycle_out_dir = check_directory( os.path.join(out_dir, 'Sequence_{} {}'.format(sequence, ci))) if isinstance(cycle, list): # for ffi in failed_frames[ci]: # cycle.insert(ffi, np.zeros((256, 256))) for frame in range(len(cycle)): # if frame in failed_frames[ci]: # continue image = np.array(cycle[frame]) cv2.imwrite( os.path.join(cycle_out_dir, 'US_2D_{}.png'.format(frame)), image) else: for frame in range(cycle.shape[2]): # if frame in failed_frames[ci]: # continue image = np.fliplr(cycle[:, :, frame]) if resize: image = cv2.resize( np.array(image), (1024, 1024), interpolation=cv2.INTER_LINEAR_EXACT) cv2.imwrite( os.path.join(cycle_out_dir, 'US_2D_{}.png'.format(frame)), image)
def _print_error_file_cycles(self): print('No usable cycles found') error_filename = self.filename.split('.')[0] error_file_dir = check_directory( os.path.join(self.output_path, 'failed_qc', 'failed_cycles')) txt_file = open( os.path.join(error_file_dir, '{}.txt'.format(self.s_sopid)), 'w') txt_file.write('No usable cycles found in case {}'.format( self.s_sopid)) txt_file.close() txt_file2 = open( os.path.join(error_file_dir, '{}.txt'.format(error_filename)), 'w') txt_file2.write( 'No usable cycles found in case {}'.format(error_filename)) txt_file2.close()
def _from_images_to_indices(self, cycles_list, dimensions_list, plot_all=False): """ The main function to control the flow and call: 1. Segmentation, which returns a list of lists (one for each cycle) of masks (one for each image). 2. Contouring, which returns a list of lists (one for each cycle) of tuples (with ordered (x,y) positions of the trace. 3. Trace, which returns the data frame with all recorded biomarkers from the provided cycles. :param cycles_list: :return: """ df_biomarkers = pd.DataFrame(columns=[ 'min', 'max', 'avg_min_basal_curv', 'avg_avg_basal_curv', 'min_delta', 'max_delta', 'amplitude_at_t' ]) # ----- SEGMENTATION --------------------------------------------------------------------------------- segmentation_list = [] df = pd.DataFrame(index=['Patient_ID'], columns=['x', 'y']) exec_net, plugin = self._get_exec_net() for cycle_i, cycle in enumerate(cycles_list): print('cycle_length: {}'.format(cycle.shape[2])) self.cycle_index = cycle_i segmentations, _ = self._segmentation_with_model( cycle, exec_net, plugin) if segmentations is not None: self._find_and_save_ed(segmentations, cycle_i) df.loc['{}_{}'.format(self.case_id, cycle_i)] = dimensions_list[cycle_i] segmentation_list.append( segmentations) # list of segemntations of single cycles else: print('Cycle failed on segmentation quality check') segmentation_list.append(None) seg_id = '{}_{}'.format(self.s_sopid, cycle_i) df_biomarkers.loc[seg_id] = [0.0] * 7 del exec_net del plugin df.to_csv( os.path.join(self.output_path, 'EDs', '{}.csv'.format(self.case_id))) # ---------------------------------------------------------------------------------------------------- # ----- CONTOURING ----------------------------------------------------------------------------------- contours_list = [] for segment_i, segment in enumerate(segmentation_list): self.cycle_index = segment_i if segment is not None: contours = Contour(segmentations_path=None, output_path=self.output_path, segmentation_cycle=segment, s_sopid=self.s_sopid, cycle_index=self.cycle_index, dimensions=dimensions_list[segment_i]) contours.lv_endo_edges() if contours.all_cycle is not None and \ len(contours.all_cycle)/cycles_list[self.cycle_index].shape[2] > 0.7: contours_list.append(contours.all_cycle ) # list of contours of single cycles else: print('Cycle failed on contouring quality check') contours_list.append(None) seg_id = '{}_{}'.format(self.s_sopid, segment_i) df_biomarkers.loc[seg_id] = [1.0] * 7 else: print('Cycle excluded due to previous segmentation failure') contours_list.append(None) # ---------------------------------------------------------------------------------------------------- # ----- CURVATURE ------------------------------------------------------------------------------------ traces_dict = {} for contour_i, contour in enumerate(contours_list): if contour is not None: trace_id = self.s_sopid + '_' + str(contour_i) trace = Trace(case_name=trace_id, contours=contour, interpolation_parameters=(None, False)) traces_dict[trace_id] = trace np.savetxt(os.path.join( self.output_path, 'Curvatures', '{}_{}.csv'.format(self.case_id, str(contour_i))), np.array(trace.ventricle_curvature), delimiter=',', fmt='%.7f') np.savetxt(os.path.join( self.output_path, 'Contours', '{}_{}.csv'.format(self.case_id, str(contour_i))), trace.data, delimiter=',', fmt='%.7f') df_biomarkers = df_biomarkers.append(trace.biomarkers) # ---------------------------------------------------------------------------------------------------- # ----- PLOTTING ------------------------------------------------------------------------------------- # biomarkers_dir = check_directory(os.path.join(self.output_path, 'biomarkers')) # df_biomarkers.to_csv(os.path.join(biomarkers_dir, '{}.csv'.format(series_uid))) df_tmp = df_biomarkers[df_biomarkers['min'] != 0] df_tmp = df_tmp[df_tmp['min'] != 1] if df_tmp.empty: self._print_error_file_cycles() return df_biomarkers # Plotting: the trace with maximum curvature of the case min_curvature_index = self._find_trace_with_minimum_curvature( df_biomarkers) self._plot_relevant_cycle(traces_dict[min_curvature_index[0]]) if plot_all: self._plot_all(segmentation_list, cycles_list, contours_list) else: # Plotting: contour of LV on the image and mask min_curv_cycle = int(min_curvature_index[0].split('_')[-1]) img_dir = check_directory( os.path.join(self.output_path, 'Seg_cont', '{}_{}'.format(self.filename, self.case_id))) print('min_curv_cycle: {}'.format(min_curv_cycle)) for i in range(len(contours_list[min_curv_cycle])): plt.subplot(121) plt.imshow(np.flip(np.array(cycles_list[min_curv_cycle][:, :, i]), axis=1), cmap='gray') plt.imshow(np.array(segmentation_list[min_curv_cycle][i]), cmap='jet', alpha=0.2) plt.subplot(122) plt.imshow(np.flip(np.array(cycles_list[min_curv_cycle][:, :, i]), axis=1), cmap='gray') plt.plot([ x[0] / dimensions_list[min_curv_cycle][0] for x in contours_list[min_curv_cycle][i] ], [ -y[1] / dimensions_list[min_curv_cycle][1] for y in contours_list[min_curv_cycle][i] ], 'y--') plt.savefig(os.path.join(img_dir, 'Seg_cont_{}'.format(i))) plt.clf() # ---------------------------------------------------------------------------------------------------- print(df_biomarkers) return df_biomarkers
def _plot_relevant_cycle(self, trace): traces_folder = check_directory( os.path.join(self.output_path, 'traces')) plot_tool = PlottingCurvature(None, traces_folder, ventricle=trace) plot_tool.plot_heatmap() plot_tool.plot_all_frames(coloring_scheme='curvature')