def create_labeled_video( config, videos, videotype="avi", shuffle=1, trainingsetindex=0, filtered=False, fastmode=True, save_frames=False, Frames2plot=None, displayedbodyparts="all", displayedindividuals="all", codec="mp4v", outputframerate=None, destfolder=None, draw_skeleton=False, trailpoints=0, displaycropped=False, color_by="bodypart", modelprefix="", track_method="", ): """ Labels the bodyparts in a video. Make sure the video is already analyzed by the function 'analyze_video' Parameters ---------- config : string Full path of the config.yaml file as a string. videos : list A list of strings containing the full paths to videos for analysis or a path to the directory, where all the videos with same extension are stored. videotype: string, optional Checks for the extension of the video in case the input to the video is a directory.\n Only videos with this extension are analyzed. The default is ``.avi`` shuffle : int, optional Number of shuffles of training dataset. Default is set to 1. trainingsetindex: int, optional Integer specifying which TrainingsetFraction to use. By default the first (note that TrainingFraction is a list in config.yaml). filtered: bool, default false Boolean variable indicating if filtered output should be plotted rather than frame-by-frame predictions. Filtered version can be calculated with deeplabcut.filterpredictions videotype: string, optional Checks for the extension of the video in case the input is a directory.\nOnly videos with this extension are analyzed. The default is ``.avi`` fastmode: bool If true uses openCV (much faster but less customization of video) vs matplotlib (if false). You can also "save_frames" individually or not in the matplotlib mode (if you set the "save_frames" variable accordingly). However, using matplotlib to create the frames it therefore allows much more flexible (one can set transparency of markers, crop, and easily customize). save_frames: bool If true creates each frame individual and then combines into a video. This variant is relatively slow as it stores all individual frames. Frames2plot: List of indices If not None & save_frames=True then the frames corresponding to the index will be plotted. For example, Frames2plot=[0,11] will plot the first and the 12th frame. displayedbodyparts: list of strings, optional This selects the body parts that are plotted in the video. Either ``all``, then all body parts from config.yaml are used orr a list of strings that are a subset of the full list. E.g. ['hand','Joystick'] for the demo Reaching-Mackenzie-2018-08-30/config.yaml to select only these two body parts. displayedindividuals: list of strings, optional Individuals plotted in the video. By default, all individuals present in the config will be showed. codec: codec for labeled video. Options see http://www.fourcc.org/codecs.php [depends on your ffmpeg installation.] outputframerate: positive number, output frame rate for labeled video (only available for the mode with saving frames.) By default: None, which results in the original video rate. destfolder: string, optional Specifies the destination folder that was used for storing analysis data (default is the path of the video). draw_skeleton: bool If ``True`` adds a line connecting the body parts making a skeleton on on each frame. The body parts to be connected and the color of these connecting lines are specified in the config file. By default: ``False`` trailpoints: int Number of revious frames whose body parts are plotted in a frame (for displaying history). Default is set to 0. displaycropped: bool, optional Specifies whether only cropped frame is displayed (with labels analyzed therein), or the original frame with the labels analyzed in the cropped subset. color_by : string, optional (default='bodypart') Coloring rule. By default, each bodypart is colored differently. If set to 'individual', points belonging to a single individual are colored the same. Examples -------- If you want to create the labeled video for only 1 video >>> deeplabcut.create_labeled_video('/analysis/project/reaching-task/config.yaml',['/analysis/project/videos/reachingvideo1.avi']) -------- If you want to create the labeled video for only 1 video and store the individual frames >>> deeplabcut.create_labeled_video('/analysis/project/reaching-task/config.yaml',['/analysis/project/videos/reachingvideo1.avi'],fastmode=True, save_frames=True) -------- If you want to create the labeled video for multiple videos >>> deeplabcut.create_labeled_video('/analysis/project/reaching-task/config.yaml',['/analysis/project/videos/reachingvideo1.avi','/analysis/project/videos/reachingvideo2.avi']) -------- If you want to create the labeled video for all the videos (as .avi extension) in a directory. >>> deeplabcut.create_labeled_video('/analysis/project/reaching-task/config.yaml',['/analysis/project/videos/']) -------- If you want to create the labeled video for all the videos (as .mp4 extension) in a directory. >>> deeplabcut.create_labeled_video('/analysis/project/reaching-task/config.yaml',['/analysis/project/videos/'],videotype='mp4') -------- """ cfg = auxiliaryfunctions.read_config(config) trainFraction = cfg["TrainingFraction"][trainingsetindex] DLCscorer, DLCscorerlegacy = auxiliaryfunctions.GetScorerName( cfg, shuffle, trainFraction, modelprefix=modelprefix ) # automatically loads corresponding model (even training iteration based on snapshot index) if save_frames: fastmode = False # otherwise one cannot save frames bodyparts = auxiliaryfunctions.IntersectionofBodyPartsandOnesGivenbyUser( cfg, displayedbodyparts) individuals = auxfun_multianimal.IntersectionofIndividualsandOnesGivenbyUser( cfg, displayedindividuals) if draw_skeleton: bodyparts2connect = cfg["skeleton"] skeleton_color = cfg["skeleton_color"] else: bodyparts2connect = None skeleton_color = None start_path = os.getcwd() Videos = auxiliaryfunctions.Getlistofvideos(videos, videotype) if not len(Videos): print( "No video(s) were found. Please check your paths and/or 'video_type'." ) return for video in Videos: videofolder = Path(video).parents[0] if destfolder is None: destfolder = videofolder # where your folder with videos is. auxiliaryfunctions.attempttomakefolder(destfolder) os.chdir(destfolder) # THE VIDEO IS STILL IN THE VIDEO FOLDER videotype = Path(video).suffix print("Starting % ", destfolder, videos) vname = str(Path(video).stem) # if notanalyzed: # notanalyzed,outdataname,sourcedataname,DLCscorer=auxiliaryfunctions.CheckifPostProcessing(folder,vname,DLCscorer,DLCscorerlegacy,suffix='checking') if filtered == True: videooutname1 = os.path.join(vname + DLCscorer + "filtered_labeled.mp4") videooutname2 = os.path.join(vname + DLCscorerlegacy + "filtered_labeled.mp4") else: videooutname1 = os.path.join(vname + DLCscorer + "_labeled.mp4") videooutname2 = os.path.join(vname + DLCscorerlegacy + "_labeled.mp4") if os.path.isfile(videooutname1) or os.path.isfile(videooutname2): print("Labeled video already created.") else: print("Loading ", video, "and data.") try: df, filepath, _, _ = auxiliaryfunctions.load_analyzed_data( destfolder, vname, DLCscorer, filtered, track_method) metadata = auxiliaryfunctions.load_video_metadata( destfolder, vname, DLCscorer) if cfg.get("multianimalproject", False): s = "_id" if color_by == "individual" else "_bp" else: s = "" videooutname = filepath.replace(".h5", f"{s}_labeled.mp4") if os.path.isfile(videooutname): print("Labeled video already created. Skipping...") continue if all(individuals): df = df.loc(axis=1)[:, individuals] cropping = metadata["data"]["cropping"] [x1, x2, y1, y2] = metadata["data"]["cropping_parameters"] labeled_bpts = [ bp for bp in df.columns.get_level_values( "bodyparts").unique() if bp in bodyparts ] if not fastmode: tmpfolder = os.path.join(str(videofolder), "temp-" + vname) if save_frames: auxiliaryfunctions.attempttomakefolder(tmpfolder) clip = vp(video) CreateVideoSlow( videooutname, clip, df, tmpfolder, cfg["dotsize"], cfg["colormap"], cfg["alphavalue"], cfg["pcutoff"], trailpoints, cropping, x1, x2, y1, y2, save_frames, labeled_bpts, outputframerate, Frames2plot, bodyparts2connect, skeleton_color, draw_skeleton, displaycropped, color_by, ) else: if (displaycropped ): # then the cropped video + the labels is depicted clip = vp( fname=video, sname=videooutname, codec=codec, sw=x2 - x1, sh=y2 - y1, ) else: # then the full video + the (perhaps in cropped mode analyzed labels) are depicted clip = vp(fname=video, sname=videooutname, codec=codec) CreateVideo( clip, df, cfg["pcutoff"], cfg["dotsize"], cfg["colormap"], labeled_bpts, trailpoints, cropping, x1, x2, y1, y2, bodyparts2connect, skeleton_color, draw_skeleton, displaycropped, color_by, ) except FileNotFoundError as e: print(e) continue os.chdir(start_path)
def proc_video( videos, destfolder, filtered, DLCscorer, DLCscorerlegacy, track_method, cfg, individuals, color_by, bodyparts, codec, bodyparts2connect, trailpoints, save_frames, outputframerate, Frames2plot, draw_skeleton, skeleton_color, displaycropped, fastmode, keypoints_only, video, ): """Helper function for create_videos Parameters ---------- """ videofolder = Path(video).parents[0] if destfolder is None: destfolder = videofolder # where your folder with videos is. auxiliaryfunctions.attempttomakefolder(destfolder) os.chdir(destfolder) # THE VIDEO IS STILL IN THE VIDEO FOLDER print("Starting to process video: {}".format(video)) vname = str(Path(video).stem) if filtered: videooutname1 = os.path.join(vname + DLCscorer + "filtered_labeled.mp4") videooutname2 = os.path.join(vname + DLCscorerlegacy + "filtered_labeled.mp4") else: videooutname1 = os.path.join(vname + DLCscorer + "_labeled.mp4") videooutname2 = os.path.join(vname + DLCscorerlegacy + "_labeled.mp4") if os.path.isfile(videooutname1) or os.path.isfile(videooutname2): print("Labeled video {} already created.".format(vname)) else: print("Loading {} and data.".format(video)) try: df, filepath, _, _ = auxiliaryfunctions.load_analyzed_data( destfolder, vname, DLCscorer, filtered, track_method) metadata = auxiliaryfunctions.load_video_metadata( destfolder, vname, DLCscorer) if cfg.get("multianimalproject", False): s = "_id" if color_by == "individual" else "_bp" else: s = "" videooutname = filepath.replace(".h5", f"{s}_labeled.mp4") if os.path.isfile(videooutname): print("Labeled video already created. Skipping...") return if all(individuals): df = df.loc(axis=1)[:, individuals] cropping = metadata["data"]["cropping"] [x1, x2, y1, y2] = metadata["data"]["cropping_parameters"] labeled_bpts = [ bp for bp in df.columns.get_level_values("bodyparts").unique() if bp in bodyparts ] if keypoints_only: # Mask rather than drop unwanted bodyparts to ensure consistent coloring mask = df.columns.get_level_values("bodyparts").isin(bodyparts) df.loc[:, ~mask] = np.nan inds = None if bodyparts2connect: all_bpts = df.columns.get_level_values("bodyparts")[::3] inds = get_segment_indices(bodyparts2connect, all_bpts) create_video_with_keypoints_only( df, videooutname, inds, cfg["pcutoff"], cfg["dotsize"], cfg["alphavalue"], skeleton_color=skeleton_color, color_by=color_by, colormap=cfg["colormap"], ) elif not fastmode: tmpfolder = os.path.join(str(videofolder), "temp-" + vname) if save_frames: auxiliaryfunctions.attempttomakefolder(tmpfolder) clip = vp(video) CreateVideoSlow( videooutname, clip, df, tmpfolder, cfg["dotsize"], cfg["colormap"], cfg["alphavalue"], cfg["pcutoff"], trailpoints, cropping, x1, x2, y1, y2, save_frames, labeled_bpts, outputframerate, Frames2plot, bodyparts2connect, skeleton_color, draw_skeleton, displaycropped, color_by, ) else: if displaycropped: # then the cropped video + the labels is depicted clip = vp( fname=video, sname=videooutname, codec=codec, sw=x2 - x1, sh=y2 - y1, fps=outputframerate, ) else: # then the full video + the (perhaps in cropped mode analyzed labels) are depicted clip = vp(fname=video, sname=videooutname, codec=codec, fps=outputframerate) CreateVideo( clip, df, cfg["pcutoff"], cfg["dotsize"], cfg["colormap"], labeled_bpts, trailpoints, cropping, x1, x2, y1, y2, bodyparts2connect, skeleton_color, draw_skeleton, displaycropped, color_by, ) except FileNotFoundError as e: print(e)
def proc_video( videos, destfolder, filtered, DLCscorer, DLCscorerlegacy, track_method, cfg, individuals, color_by, bodyparts, codec, bodyparts2connect, trailpoints, save_frames, outputframerate, Frames2plot, draw_skeleton, skeleton_color, displaycropped, fastmode, video, ): """Helper function for create_videos Parameters ---------- """ videofolder = Path(video).parents[0] if destfolder is None: destfolder = videofolder # where your folder with videos is. auxiliaryfunctions.attempttomakefolder(destfolder) os.chdir(destfolder) # THE VIDEO IS STILL IN THE VIDEO FOLDER print("Starting to process video: {}".format(video)) vname = str(Path(video).stem) if filtered: videooutname1 = os.path.join(vname + DLCscorer + "filtered_labeled.mp4") videooutname2 = os.path.join(vname + DLCscorerlegacy + "filtered_labeled.mp4") else: videooutname1 = os.path.join(vname + DLCscorer + "_labeled.mp4") videooutname2 = os.path.join(vname + DLCscorerlegacy + "_labeled.mp4") if os.path.isfile(videooutname1) or os.path.isfile(videooutname2): print("Labeled video {} already created.".format(vname)) else: print("Loading {} and data.".format(video)) try: df, filepath, _, _ = auxiliaryfunctions.load_analyzed_data( destfolder, vname, DLCscorer, filtered, track_method ) metadata = auxiliaryfunctions.load_video_metadata( destfolder, vname, DLCscorer ) if cfg.get("multianimalproject", False): s = "_id" if color_by == "individual" else "_bp" else: s = "" # Adds support for multi_output mode. Adds extra bodyparts found in the data but not in the config.yaml. # Only works if "multi_output_format" is set to "separate-bodyparts". cmp_set = set( idx[1] for idx in df if (idx[1] in bodyparts or is_extension_part(idx[1], bodyparts)) ) bodyparts = [ bp for bp in df.columns.get_level_values("bodyparts").unique() if (bp in cmp_set) ] # print(bodyparts) videooutname = filepath.replace(".h5", f"{s}_labeled.mp4") if os.path.isfile(videooutname): print("Labeled video already created. Skipping...") return if all(individuals): df = df.loc(axis=1)[:, individuals] cropping = metadata["data"]["cropping"] [x1, x2, y1, y2] = metadata["data"]["cropping_parameters"] labeled_bpts = [ bp for bp in df.columns.get_level_values("bodyparts").unique() if bp in bodyparts ] if not fastmode: tmpfolder = os.path.join(str(videofolder), "temp-" + vname) if save_frames: auxiliaryfunctions.attempttomakefolder(tmpfolder) clip = vp(video) CreateVideoSlow( videooutname, clip, df, tmpfolder, cfg["dotsize"], cfg["colormap"], cfg["alphavalue"], cfg["pcutoff"], trailpoints, cropping, x1, x2, y1, y2, save_frames, labeled_bpts, outputframerate, Frames2plot, bodyparts2connect, skeleton_color, draw_skeleton, displaycropped, color_by, ) else: if displaycropped: # then the cropped video + the labels is depicted clip = vp( fname=video, sname=videooutname, codec=codec, sw=x2 - x1, sh=y2 - y1, ) else: # then the full video + the (perhaps in cropped mode analyzed labels) are depicted clip = vp(fname=video, sname=videooutname, codec=codec) CreateVideo( clip, df, cfg["pcutoff"], cfg["dotsize"], cfg["colormap"], labeled_bpts, trailpoints, cropping, x1, x2, y1, y2, bodyparts2connect, skeleton_color, draw_skeleton, displaycropped, color_by, ) except FileNotFoundError as e: print(e)