def __init__(self, echonet_path=None, output_path=None): if echonet_path is not None: self.echonet_path = echonet_path self.movies_path = os.path.join(echonet_path, 'GoodX2Y2') self.output_path = check_directory( os.path.join(echonet_path, 'Output')) if output_path is not None: self.output_path = check_directory(output_path) self.df_volume_tracings = None self.list_of_movie_files = None self.movie_name = None
def save_all_results(self, save_markers=True, save_contours=False, save_wt=False, save_curvature=False, save_images=False): markers_cohort = [] for seg_file in self.seg_files: filename = os.path.basename(seg_file).split('.')[0] self._lv_edges(seg_file) if save_contours: out_dir = check_directory( os.path.join(self.output_path, 'Contours')) np.savetxt( os.path.join(out_dir, filename + '_endocardium.csv'), self.endo_sorted_edge) np.savetxt(os.path.join(out_dir, filename + '_epicardium.csv'), self.epi_sorted_edge) markers_cohort.append(self._lv_markers(seg_file)) if save_images: out_dir = check_directory( os.path.join(self.output_path, 'Pictures')) self.plot_mask_with_contour(self.endo_sorted_edge, self.epi_sorted_edge, save_file=os.path.join( out_dir, filename + '_contours.png')) self.plot_wt( save_file=os.path.join(out_dir, filename + '_wall_thickness.png')) if save_wt: out_dir = check_directory( os.path.join(self.output_path, 'Wall_thickness')) np.savetxt( os.path.join(out_dir, filename + '_wall_thickness.csv'), self.wall_thickness) if save_curvature: out_dir = check_directory( os.path.join(self.output_path, 'Curvature')) np.savetxt(os.path.join(out_dir, filename + '_curvature.csv'), self.curvature) if save_markers: out_dir = check_directory( os.path.join(self.output_path, 'Markers')) df_cohort = pd.DataFrame(markers_cohort) date_id = datetime.now().isoformat(timespec='minutes').replace( 'T', '_').replace(':', '-') df_cohort.to_csv( os.path.join(out_dir, 'Cohort_markers_{}.csv'.format(date_id)))
def _save_screenshots(self, dict_contours): screenshot_path = check_directory( os.path.join(self.output_path, 'Phase_images')) default_im_size = 1024 frame_images = self.process_movie(dict_contours['ed']['frame'], dict_contours['es']['frame']) for phase in ['ed', 'es']: orig_ed_height, orig_ed_width = frame_images[phase].shape[:2] drawing_contours = np.array([ dict_contours[phase]['contour'][:, 0] * default_im_size / orig_ed_height, dict_contours[phase]['contour'][:, 1] * default_im_size / orig_ed_width ]).T drawing_image = cv2.resize(frame_images[phase], (default_im_size, default_im_size)) cv2.polylines(drawing_image, [np.int32(drawing_contours)], isClosed=False, color=(255, 0, 0), thickness=5) cv2.imwrite( os.path.join(screenshot_path, "{}_{}.jpg".format(dict_contours['id'], phase)), drawing_image)
def _save_curvature_markers(self, dict_contours): curvature_indices_path = check_directory( os.path.join(self.output_path, 'Curvature_indices')) curvature_markers = [] for phase in ('ed', 'es'): curvature_markers.append(dict_contours[phase]['curvature_markers']) df_curvature = pd.DataFrame(curvature_markers, index=['ed', 'es']) df_curvature.to_csv( os.path.join(curvature_indices_path, dict_contours['id'] + '_curv.csv'))
def _save_contours(self, dict_contours): contours_path = check_directory( os.path.join(self.output_path, 'Contours')) np.savetxt(os.path.join(contours_path, '{}_ed.csv'.format(dict_contours['id'])), dict_contours['ed']['contour'], fmt='%1.4f', delimiter=',') np.savetxt(os.path.join(contours_path, '{}_es.csv'.format(dict_contours['id'])), dict_contours['es']['contour'], fmt='%1.4f', delimiter=',')
def __init__(self, segmentations_path, output_path=None, image_info_file=None, pixel_size=None, scale=False, smoothing_resolution=500, plot_smoothing_results=False): """ A class to calculate the curvature and wall thickness of the left ventricle based on the NTNU segmentation model :param segmentations_path: folder with segmentation images (with .png extension) :param output_path: results will be stored in this folder :param image_info_file: a csv file, containing information about the resolution of the original image. It should contain three columns - 'id', with the name of the segmentation file (e.g. segmentation123.png), and 'voxel_size_width' and 'voxel_size_height', with values that are used to resize the calculated markers to a proper scale. :param pixel_size: (tuple) if scalling factors are the same for all images in the segmentations_path, provide a tuple with width and height of the pixels (in this order) :param scale: (bool) whether or not to scale the markers :param smoothing_resulotion: (int) the number of points in the smooth version of the endocardium. The epicardium will become 5 times as long, by default (for more accurate wall thickness measurement) :param plot_smoothing_results: (bool) whether or not to plot the results of smoothing """ self.segmentations_path = segmentations_path if output_path is not None: self.output_path = check_directory(output_path) elif segmentations_path is not None: self.output_path = check_directory( os.path.join(segmentations_path, 'output')) else: self.output_path = check_directory( os.path.join(os.getcwd(), 'output')) if pixel_size is not None: self.pixel_size = pixel_size # either provided explicitly else: self.pixel_size = (1, 1) self.image_info_file = image_info_file if self.pixel_size == (1, 1) and self.image_info_file is None: print( 'Warning! No dimensions of the mask files provided. Set to (1, 1)' ) if self.segmentations_path is not None: self.seg_files = glob.glob( os.path.join(self.segmentations_path, '*.png')) # list of mask files self.seg_files.sort() self.scale = scale self.plot_smoothing_results = plot_smoothing_results self.img_index = 0 self.gray_mask = None self.endo_sorted_edge = list() self.epi_sorted_edge = list() self.mask_values = { 'LV_bp': 85, 'LV_myo': 170 } # in NTNU model, these were the default values self.is_endo = True self.smoothing_resolution = smoothing_resolution self.distance_matrix = np.zeros(1) self.wall_thickness = None self.wall_thickness_markers = None self.curvature = None self.endo_curvature_markers = None self.epi_curvature_markers = None