Exemple #1
0
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)