def dlc3d_video_migrate(config_path, root, many=False, test=False): ''' Migrate DeepCage videos to DeepCage related DeepLabCut 3D projects Parameters ---------- config_path : string Absolute path of the project config.yaml file. root : string Absolute path for the root directory of function operation many : bool; default False Bool indicating if root stores many projects. False means the root is a project root test : bool; default False Bool indicating if the respective function call is for testing. If True, the function will not copy video files ''' dlc3d_cfgs = get_dlc3d_configs(config_path) pairs = tuple(dlc3d_cfgs.keys()) if many is False: result = copy_videos_from_root(root, dlc3d_cfgs, test) else: project_dirs = glob(os.path.join(root, '*/')) result = {} for project_dir in project_dirs: project_name = Path(project_dir).stem result[project_name] = copy_videos_from_root( project_dir, dlc3d_cfgs, test) print('Overview of videos found for each pair:\n%s' % result) return result
def detect_2d_coords(config_path, suffix='filtered.h5', bonvideos=False): ''' This function detects and returns the state of deeplabcut-triangulated coordinate h5 files (can be changed) Parameters ---------- config_path : string Absolute path of the project config.yaml file. suffix : string The suffix in the DeepLabCut 3D project triangualtion result storage files Example ------- ''' cfg = read_config(config_path) dlc3d_cfgs = get_dlc3d_configs(config_path) results_path = Path(cfg['results_path']) triangulated = results_path / 'triangulated' experiments = glob(str(triangulated / '*/')) if experiments == []: msg = 'Could not find any triangulated coordinates in %s' % triangulated raise ValueError(msg) coords = {} for exp_path in experiments: exp_dir_name = os.path.basename(exp_path) if bonvideos is True: animal, trial, date = exp_dir_name.split('_') coords[(animal, trial, date)] = {} else: coords[exp_dir_name] = {} regions_of_interest = {} for hdf_path in glob(os.path.join(exp_path, '**/*' + suffix)): pair_info = os.path.basename(os.path.dirname(hdf_path)).split('_') if len(pair_info) == 2: cam1, cam2 = pair_info else: idx_, cam1, cam2 = pair_info pair = (cam1, cam2) df = pd.read_hdf(os.path.realpath(hdf_path)) exp_regions_of_interest = df.columns.levels[0] regions_of_interest[pair] = exp_regions_of_interest coord = {roi: df[roi].values for roi in exp_regions_of_interest} if bonvideos is True: coords[(animal, trial, date)][pair] = coord else: coords[exp_dir_name][pair] = coord return coords
def visualize_triangulation(config_path, undistort=True, decrement=False, save=True): dlc3d_cfgs = get_dlc3d_configs(config_path) basis_labels = get_labels(config_path) cfg = read_config(config_path) test_dir = os.path.join(cfg['data_path'], 'test') if not os.path.exists(test_dir): os.mkdir(test_dir) fig = plt.figure(figsize=(14, 10)) # Get non-corner pairs by splicing pairs = tuple(PAIR_IDXS.keys())[::2] pair_ax = {} for i, pair in enumerate(pairs): dlc3d_cfg = dlc3d_cfgs[pair] cam1, cam2 = pair # Prepare camera plot labels cam_labels = get_paired_labels(config_path, pair)['decrement' if decrement is True else 'normal'] # Triangulate the two sets of labels, and map them to 3D trian_dict, trian_coord = triangulate_raw_2d_camera_coords( dlc3d_cfg, cam1_coords=tuple(cam_labels[cam1].values()), cam2_coords=tuple(cam_labels[cam2].values()), keys=cam_labels[cam1], undistort=undistort ) pair_ax[pair] = fig.add_subplot(2, 2, i+1, projection='3d') for label, coord in trian_dict.items(): pair_ax[pair].scatter(*coord, label=label) if CAMERAS[cam1][0][1] == 'left': c_origin = trian_coord[0] + (trian_coord[1] - trian_coord[0]) / 2 else: c_origin = trian_coord[1] + (trian_coord[0] - trian_coord[1]) / 2 pair_ax[pair].scatter(*c_origin, label='computed origin') pair_ax[pair].legend() angle_origins = vg.angle(trian_dict['origin'], c_origin) pair_ax[pair].set_title('%s %s\nInnerAngle(orgin, c_origin): %.2f deg' % (*pair, angle_origins)).set_y(1.005) fig.suptitle('Triangulation visualization', fontsize=20) if save is True: fig.savefig(os.path.join(test_dir, 'visualize_triangulation.png')) return fig, pair_ax
def OE_get_triangulated_basis(config_path, pair, undistort=True, keys=False): from deepcage.compute.triangulate import triangulate_raw_2d_camera_coords from deepcage.project.get import get_dlc3d_configs, get_labels cam1, cam2 = pair labels = get_labels(config_path) basis_labels = OE_get_paired_labels(config_path, pair) cam1_labels, cam2_labels = basis_labels.values() return triangulate_raw_2d_camera_coords( get_dlc3d_configs(config_path)[pair], cam1_coords=tuple(cam1_labels.values()), cam2_coords=tuple(cam2_labels.values()), undistort=undistort, keys=None if keys is False else tuple(cam1_labels.keys()))
def visualize_basis_vectors(config_path, undistort=True, normalize=True, decrement=False, stereo_cam_units=None, save=True): ''' Parameters ---------- config_path : string Absolute path of the project config.yaml file. ''' if stereo_cam_units is None: stereo_cam_units, orig_maps = create_stereo_cam_origmap(config_path, undistort=undistort, normalize=normalize, decrement=decrement, save=False) cfg = read_config(config_path) dlc3d_cfgs = get_dlc3d_configs(config_path) test_dir = os.path.join(cfg['data_path'], 'test') if not os.path.exists(test_dir): os.mkdir(test_dir) pairs = tuple(dlc3d_cfgs.keys()) pair_num = int(len(pairs) / 2) fig = plt.figure(figsize=(14, 8)) ax_duo = {} for i in range(pair_num): pair1 = pairs[i] reds = iter(plt.cm.Reds(np.linspace(0.38, 0.62, 3))) pair2 = pair_cycler(i+4, pairs=pairs) blues = iter(plt.cm.Blues(np.linspace(0.38, 0.62, 3))) ax_duo[(pair1, pair2)] = fig.add_subplot(2, 2, i+1, projection='3d') for pair, color in zip((pair1, pair2), (reds, blues)): axes = list(stereo_cam_units[pair].values())[:3] initials = pair[0][0] + pair[1][0] for i, axis in enumerate(axes): ax_duo[(pair1, pair2)].plot( [0, axis[0]], [0, axis[1]], [0, axis[2]],'-', c=next(color), label=f'{initials}: r{i}' ) ax_duo[(pair1, pair2)].legend(loc=2) ax_duo[(pair1, pair2)].set_title('%s %s and %s %s' % (*pair1, *pair2)).set_y(1.015) if save is True: fig.savefig( os.path.join(test_dir, 'visualize_basis_vectors.png') ) return fig, ax_duo
def detect_triangulation_result(config_path, filter_low_likelihood=True, pcutoff=0.1, undistorted=True, suffix='_DLC_3D.h5', change_basis=False, bonvideos=False): ''' This function detects and returns the state of deeplabcut-triangulated coordinate h5 files (can be changed) Parameters ---------- config_path : string Absolute path of the project config.yaml file. suffix : string The suffix in the DeepLabCut 3D project triangualtion result storage files change_basis : boolean Boolean stating wether the function is within a change basis workflow Example ------- ''' suffix_split = suffix.split('.') if len(suffix_split) > 1: if suffix_split[-1] != 'h5': msg = 'Invalid file extension in suffix: %s' % suffix raise ValueError(msg) else: suffix = suffix + '.h5' cfg = read_config(config_path) dlc3d_cfgs = get_dlc3d_configs(config_path) results_path = Path(cfg['results_path']) triangulated = results_path / ('undistorted' if undistorted is True else 'distorted') / 'triangulated' experiments = glob(str(triangulated / '*/')) if experiments == []: msg = 'Could not find any triangulated coordinates in %s' % triangulated raise ValueError(msg) # Detect triangulation results in related DeepLabCut 3D projects # Analyse the number of occurances of hdf across projects missing = 0 status, coords, likelihoods, pairs = {}, {}, {}, {} for exp_path in experiments: exp_dir_name = os.path.basename(exp_path) if bonvideos is True: animal, trial, date = exp_dir_name.split('_') coords[(animal, trial, date)], likelihoods[(animal, trial, date)] = {}, {} else: coords[exp_dir_name], likelihoods[exp_dir_name] = {}, {} regions_of_interest = {} for hdf_path in glob(os.path.join(exp_path, '**/*' + suffix)): pair_dir = os.path.dirname(hdf_path) pair_info = os.path.basename(pair_dir).split('_') if len(pair_info) == 2: cam1, cam2 = pair_info else: idx_, cam1, cam2 = pair_info pair = (cam1, cam2) df = pd.read_hdf(os.path.realpath(hdf_path))['DLC_3D'] exp_regions_of_interest = df.columns.levels[0] regions_of_interest[pair] = exp_regions_of_interest if filter_low_likelihood is True: try: cam1_prediction_2d = pd.read_hdf( glob(os.path.join(pair_dir, f'*{cam1}*filtered.h5'))[0]) cam2_prediction_2d = pd.read_hdf( glob(os.path.join(pair_dir, f'*{cam2}*filtered.h5'))[0]) except FileNotFoundError: print( "No filtered predictions found. Will use the unfiltered predictions." ) cam1_prediction_2d = pd.read_hdf( glob(os.path.join(pair_dir, f'*{cam1}*.h5'))[0]) cam2_prediction_2d = pd.read_hdf( glob(os.path.join(pair_dir, f'*{cam2}*.h5'))[0]) coord, roi_likelihood = {}, {} for roi in exp_regions_of_interest: cam1_likelihood = cam1_prediction_2d[ cam1_prediction_2d.keys()[0] [0]][roi]['likelihood'].values cam2_likelihood = cam2_prediction_2d[ cam2_prediction_2d.keys()[0] [0]][roi]['likelihood'].values coord_likelihood = np.dstack( (cam1_likelihood, cam2_likelihood))[0] coord_idxs = np.all(coord_likelihood < pcutoff, axis=1) df[roi].loc[coord_idxs] = np.nan coord[roi] = df[roi].values roi_likelihood[roi] = coord_likelihood else: coord = { roi: df[roi].values for roi in exp_regions_of_interest } if bonvideos is True: coords[(animal, trial, date)][pair] = coord if filter_low_likelihood is True: likelihoods[(animal, trial, date)][pair] = roi_likelihood else: coords[exp_dir_name][pair] = coord if filter_low_likelihood is True: likelihoods[exp_dir_name][pair] = roi_likelihood # print(1) # print(all([exp_regions_of_interest == rsoi for rsoi in regions_of_interest])) # if not all(all([exp_regions_of_interest == rsoi for rsoi in regions_of_interest])): # save_path = os.path.join(exp_path, 'rsoi_incom_%s_%s_%s.xlsx' % (animal, trial, date)) # pd.DataFrame.from_dict(regions_of_interest).to_excel(save_path) # print('Inconsistencies in exp %s %s %s were found.\nAn overview was saved:\n%s\n' % ( # animal, trial, date, save_path # ) # ) # missing += 1 if missing == 0: print('Triangulations files detected, and verified') if change_basis is True: print('Proceeding to changing basis') else: print('The current DeepCage project is ready for changing basis') return coords, likelihoods if filter_low_likelihood is True else coords else: if missing == 1: msg = 'Inconsistencies in regions of interest was found in one experiment' else: msg = 'Inconsistencies in regions of interest were found in %d experiments' % missing raise ValueError(msg)
def dlc3d_create_labeled_video(config_path, fps=20, undistort=True, video_root=None, video_dir_hierarchy=False, remove_origin=False): ''' Augmented function from https://github.com/AlexEMG/DeepLabCut Create pairwise videos ''' from deepcage.auxiliary.detect import detect_videos_in_hierarchy start_path = os.getcwd() cfg = read_config(config_path) result_path = Path(cfg['results_path']) triangulate_path = result_path / ("undistorted" if undistort is True else "distorted") / 'triangulated' if not os.path.exists(triangulate_path) or 0 == len(glob(os.path.join(triangulate_path, '*'))): msg = f'Could not detect triangulated coordinates in {triangulate_path}' raise ValueError(msg) if remove_origin is True: basis_result_path = os.path.join(cfg['data_path'], 'cb_result.pickle') try: with open(basis_result_path, 'rb') as infile: stereo_cam_units, orig_maps = pickle.load(infile) except FileNotFoundError: msg = f'Could not detect results from deepcage.compute.generate_linear_map() in:\n{basis_result_path}' raise FileNotFoundError(msg) skipped = [] dlc3d_cfgs = get_dlc3d_configs(config_path) futures = {} # with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor: for pair, dlc3d_cfg_path in dlc3d_cfgs.items(): dlc3d_cfg = read_config(dlc3d_cfg_path) pcutoff = dlc3d_cfg['pcutoff'] markerSize = dlc3d_cfg['dotsize'] alphaValue = dlc3d_cfg['alphaValue'] cmap = dlc3d_cfg['colormap'] skeleton_color = dlc3d_cfg['skeleton_color'] scorer_3d = dlc3d_cfg['scorername_3d'] bodyparts2connect = dlc3d_cfg['skeleton'] bodyparts2plot = list(np.unique([val for sublist in bodyparts2connect for val in sublist])) color = plt.cm.get_cmap(cmap, len(bodyparts2plot)) cam1, cam2 = pair if video_dir_hierarchy is True: hierarchy, _ = detect_videos_in_hierarchy( video_root, deep_dict=True ) for exp_id, pairs in hierarchy.items(): for pair_info, cams in pairs.items(): pair_idx, cam1, cam2 = pair_info.split('_') pair = (cam1, cam2) cam1_video, cam2_video = cams.values() info = exp_id futures[create_video( # Paths (triangulate_path / exp_id / pair_info), cam1_video, cam2_video, # ID info, pair, # Config dlc3d_cfg, pcutoff, markerSize, alphaValue, cmap, skeleton_color, scorer_3d, bodyparts2plot, bodyparts2connect, color, # Style origin_to_remove=orig_maps[pair]['origin'] if remove_origin is True else None, new_path=True )] = (*info, pair) else: if video_root is None: video_root = os.path.join(os.path.dirname(dlc3d_cfg_path), 'videos') else: video_root = os.path.realpath(video_root) cam1_videos = glob(os.path.join(video_root, (f'*{cam1}*'))) cam2_videos = glob(os.path.join(video_root, (f'*{cam2}*'))) with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor: for i, v_path in enumerate(cam1_videos): _, video_name = os.path.split(v_path) cam1_video, cam2_video = cam1_videos[i], cam2_videos[i] info = video_name.replace('.avi', '').split('_') futures[executor.submit(create_video, # Paths triangulate_path, cam1_video, cam2_video, # ID info, pair, # Config dlc3d_cfg, pcutoff, markerSize, alphaValue, cmap, skeleton_color, scorer_3d, bodyparts2plot, bodyparts2connect, color, # Style origin_to_remove=orig_maps[pair]['origin'] if remove_origin is True else None, new_path=True, fps=fps )] = (*info, pair) for future in concurrent.futures.as_completed(futures): video_id = futures[future] try: result = future.result() except Exception as exc: print('%s generated an exception: %s' % (video_id, exc)) else: print('%s = %s' % (video_id, result)) os.chdir(start_path)
def visualize_workflow(config_path, undistort=True, normalize=True, decrement=False, save=True): ''' Parameters ---------- config_path : string Absolute path of the project config.yaml file. ''' import matplotlib.image as image dlc3d_cfgs = get_dlc3d_configs(config_path) basis_labels = get_labels(config_path) cfg = read_config(config_path) test_dir = os.path.join(cfg['data_path'], 'test') figure_dir = os.path.join(test_dir, 'visualize_workflow') if not os.path.exists(figure_dir): os.makedirs(figure_dir) n = np.linspace(-1, 5, 100) pairs = tuple(dlc3d_cfgs.keys()) for pair in pairs: cam1, cam2 = pair fig = plt.figure(figsize=(12, 10)) ax = { 'trian': fig.add_subplot(221, projection='3d'), 'basis': fig.add_subplot(222, projection='3d'), 'cam1': fig.add_subplot(223), 'cam2': fig.add_subplot(224) } # Get camera plot labels cam_labels = get_paired_labels(config_path, pair)['decrement' if decrement is True else 'normal'] # Plot manual labels for cam, cax in zip(pair, (ax['cam1'], ax['cam2'])): # Add respective calibration image as background img_cam = image.imread(glob(os.path.join(cfg['calibration_path'], cam+'*'))[0]) cax.imshow(img_cam) cmap = iter(plt.cm.rainbow(np.linspace( 0, 1, len(cam_labels[cam]) ))) for (label, coord), color in zip(cam_labels[cam].items(), cmap): cax.set_title((cam, 'labels')).set_y(1.005) cax.scatter(*coord, c=color, label=label) cax.legend() # Triangulate the two sets of labels, and map them to 3D dlc3d_cfg = dlc3d_cfgs[pair] trian_dict, trian = triangulate_basis_labels( dlc3d_cfg, cam_labels, pair, undistort=undistort, decrement=decrement, keys=True ) cmap = iter(plt.cm.rainbow(np.linspace( 0, 1, len(trian_dict)+1) )) for (label, coord), color in zip(trian_dict.items(), cmap): ax['trian'].scatter(*(coord - trian_dict['origin']), c=color, label=label) if CAMERAS[cam1][0][1] == 'left': c_origin = trian[0] + (trian[1] - trian[0]) / 2 else: c_origin = trian[1] + (trian[0] - trian[1]) / 2 c_origin -= trian_dict['origin'] ax['trian'].scatter(*c_origin, c=next(cmap), label='computed origin') ax['trian'].set_title('Triangualted').set_y(1.005) ax['trian'].legend() ax['trian'].set_xlabel('X', fontsize=10) ax['trian'].set_ylabel('Y', fontsize=10) ax['trian'].set_zlabel('Z', fontsize=10) _, orig_map = compute_basis_vectors(trian, pair, normalize=normalize, decrement=decrement) r = [] for axis in orig_map['map'].T: r.append(n * axis[np.newaxis, :].T) r_1, r_2, r_3 = r ax['basis'].plot(*r_1, label='r1/x') ax['basis'].plot(*r_2, label='r2/y') ax['basis'].plot(*r_3, label='r3/z') # Angles i, ii, iii = orig_map['map'].T i_ii = vg.angle(i, ii) i_iii = vg.angle(i, iii) ii_iii = vg.angle(ii, iii) title_text2 = 'r1-r2: %3f r1-r3: %3f\nr2-r3: %3f' % (i_ii, i_iii, ii_iii) ax['basis'].set_title(title_text2).set_y(1.005) ax['basis'].legend() ax['basis'].set_xticklabels([]) ax['basis'].set_yticklabels([]) ax['basis'].set_zticklabels([]) ax['basis'].set_xlabel('X', fontsize=10) ax['basis'].set_ylabel('Y', fontsize=10) ax['basis'].set_zlabel('Z', fontsize=10) if save is True: fig.savefig( os.path.join(figure_dir, '%d_%s_%s.png' % (PAIR_IDXS[pair], *pair)) ) return fig, ax
def visualize_basis_vectors_single(config_path, undistort=True, normalize=True, decrement=False, stereo_cam_units=None, save=True): ''' Parameters ---------- config_path : string Absolute path of the project config.yaml file. ''' if stereo_cam_units is None: stereo_cam_units, orig_maps = create_stereo_cam_origmap( config_path, undistort=undistort, normalize=normalize, decrement=False, save=False ) dlc3d_cfgs = get_dlc3d_configs(config_path) cfg = read_config(config_path) test_dir = os.path.join(cfg['data_path'], 'test') if not os.path.exists(test_dir): os.mkdir(test_dir) pairs = tuple(dlc3d_cfgs.keys()) cmap = iter(plt.cm.rainbow(np.linspace(0, 1, 2*len(pairs)-2))) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') c_spacing = 1 / (len(pairs) - 2) for i, pair in enumerate(pairs): cam1, cam2 = pair rem_space = c_spacing * i cmap = plt.cm.rainbow(np.linspace(rem_space, rem_space+0.12, 3)) ax.plot( [0, stereo_cam_units[pair]['x-axis'][0]], [0, stereo_cam_units[pair]['x-axis'][1]], [0, stereo_cam_units[pair]['x-axis'][2]], label='%s %s r1/x' % pair, c=cmap[0] ) # ax.text(*t_1, label='r1', c=cmap[0]) ax.plot( [0, stereo_cam_units[pair]['y-axis'][0]], [0, stereo_cam_units[pair]['y-axis'][1]], [0, stereo_cam_units[pair]['y-axis'][2]], label='%s %s r2/y' % pair, c=cmap[1] ) # ax.text(*t_2, label='r2', c=cmap[1]) ax.plot( [0, stereo_cam_units[pair]['z-axis'][0]], [0, stereo_cam_units[pair]['z-axis'][1]], [0, stereo_cam_units[pair]['z-axis'][2]], label='%s %s r3/z' % pair, c=cmap[2] ) # ax.text(*t_3, label='r3', c=cmap[2]) ax.set_title('Basis comparison', fontsize=20).set_y(1.005) ax.legend(loc=2) if save is True: fig.savefig( os.path.join(test_dir, 'visualize_basis_vectors.png') ) return fig, ax
def map_experiment(config_path, undistort=True, percentiles=(5, 95), use_saved_origmap=True, normalize=True, suffix='_DLC_3D.h5', bonvideos=False, save=True, paralell=False, label_getter=None, **kwargs): ''' This function changes the basis of deeplabcut-triangulated that are 3D. Parameters ---------- config_path : string Absolute path of the project config.yaml file. linear_maps : {string: numpy.array} (3, 3) array that stores the linear map for changing basis suffix : string The suffix in the DeepLabCut 3D project triangualtion result storage files cbv_kwargs : dictionary Keyword arguments for compute_basis_vectors() Example ------- ''' coords, likelihoods = detect_triangulation_result(config_path, undistorted=undistort, suffix=suffix, change_basis=True, bonvideos=bonvideos) print(likelihoods) if coords is False: print( 'According to the DeepCage triangulated coordinates detection algorithm this project is not ready for changing basis' ) return False cfg = read_config(config_path) data_path = os.path.realpath(cfg['data_path']) result_path = cfg['results_path'] dlc3d_cfgs = get_dlc3d_configs(config_path) if use_saved_origmap is True: basis_result_path = os.path.join(data_path, 'cb_result.pickle') try: with open(basis_result_path, 'rb') as infile: stereo_cam_units, orig_maps = pickle.load(infile) except FileNotFoundError: msg = 'Could not detect results from deepcage.compute.generate_linear_map() in:\n' \ + basis_result_path raise FileNotFoundError(msg) else: stereo_cam_units, orig_maps = create_stereo_cam_origmap( config_path, undistort=undistort, decrement=False, save=False, normalize=normalize, **kwargs) dfs = {} cpu_cores = cpu_count(logical=False) if paralell is False or cpu_cores < 2: for info, pair_roi_df in coords.items(): # info = (animal, trial, date) dfs[info] = sort_coords_in_df(pair_roi_df, orig_maps, percentiles) else: submissions = {} workers = 4 if cpu_cores < 8 else 8 with concurrent.futures.ProcessPoolExecutor( max_workers=workers) as executor: for info, pair_roi_df in coords.items(): # info = (animal, trial, date) submissions[executor.submit(sort_coords_in_df, pair_roi_df, orig_maps)] = info for future in submissions: info = submissions[future] if info not in dfs: dfs[info] = {} try: dfs[info][(roi, pair)] = future.result() except Exception as exc: print('%s generated an exception: %s' % (submissions[future], exc)) if save is True: # print('Attempting to save new coordinates to result folder:\n%s' % result_path) for info, df in dfs.items(): df_name = 'mapped' for i in info.split('_'): df_name += '_' + i file_path = os.path.join(result_path, df_name) df.to_hdf(file_path + '.h5', key=df_name if bonvideos is False else 'a%st%sd%s' % info) df.to_csv(file_path + '.csv') df.to_excel(file_path + '.xlsx') print('The mapped coordinates of %s have been saved to\n%s\n' % (info, file_path)) print('DONE: Basis changed') return dfs
def create_stereo_cam_origmap(config_path, undistort=True, decrement=False, save=True, labels_are2d=True, labels_getter=get_paired_labels, basis_computer=compute_basis_vectors, **cbv_kwargs): ''' Parameters ---------- config_path : string Absolute path of the project config.yaml file. cbv_kwargs : dictionary Keyword arguments for compute_basis_vectors() ''' cfg = read_config(config_path) dlc3d_cfgs = get_dlc3d_configs(config_path) data_path = os.path.realpath(cfg['data_path']) if save is True: basis_result_path = os.path.join(data_path, 'cb_result.pickle') dataframe_path = os.path.join(data_path, 'basis_vectors.xlsx') if os.path.exists(basis_result_path) and os.path.exists( dataframe_path): msg = f'Please remove old analysis files before proceeding. File paths:\n{basis_result_path}\n{dataframe_path}' elif os.path.exists(basis_result_path): msg = f'Please remove old analysis file before proceeding. File paths:\n{basis_result_path}' elif os.path.exists(dataframe_path): msg = f'Please remove old analysis file before proceeding. File paths:\n{dataframe_path}\n' pairs = tuple(dlc3d_cfgs.keys()) stereo_cam_units, orig_maps = {}, {} for pair in pairs: cam1, cam2 = pair dlc3d_cfg = dlc3d_cfgs[pair] basis_labels = labels_getter(config_path, pair) if labels_getter is get_paired_labels: basis_labels = basis_labels[ 'decrement' if decrement is True else 'normal'] if labels_are2d is True: trian = triangulate_basis_labels(dlc3d_cfg, basis_labels, pair, undistort=undistort, decrement=decrement) else: trian = basis_labels stereo_cam_units[pair], orig_maps[pair] = basis_computer( trian, pair, decrement=decrement, **cbv_kwargs) if save is True: with open(basis_result_path, 'wb') as outfile: pickle.dump((stereo_cam_units, orig_maps), outfile) print('Saved linear map to:\n{}'.format(basis_result_path)) pd.DataFrame.from_dict(stereo_cam_units).to_excel(dataframe_path) print('Saved excel file containing the computed basis vectors to:\n{}'. format(dataframe_path)) print('Returning dictionary containing the computed linear maps') return stereo_cam_units, orig_maps