예제 #1
0
 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()
예제 #2
0
 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()
예제 #3
0
 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()
예제 #4
0
    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)
예제 #5
0
 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()
예제 #6
0
    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
예제 #7
0
 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')