def add_new_videos(_, *args, **kwargs): """ Add new videos to the config file at any stage of the project.\n Options\n ----------\n config : string\n String containing the full path of the config file in the project. videos : list \n A list of string containing the full paths of the videos to include in the project. copy_videos : bool, optional\n If this is set to True, the symlink of the videos are copied to the project/videos directory. The default is ``True``; if provided it must be either ``True`` or ``False`` Examples\n --------\n >>> python3 dlc.py add_new_videos /home/project/reaching-task-Tanmay-2018-08-23/config.yaml /data/videos/mouse5.avi """ from deeplabcut.create_project import add add.add_new_videos(*args, **kwargs)
def ExtractFramesbasedonPreselection(Index, extractionalgorithm, Dataframe, dataname, scorer, video, cfg, config, opencv=True, cluster_resizewidth=30, cluster_color=False, savelabeled=True): from deeplabcut.create_project import add start = cfg['start'] stop = cfg['stop'] numframes2extract = cfg['numframes2pick'] bodyparts = cfg['bodyparts'] videofolder = str(Path(video).parents[0]) vname = str(Path(video).stem) tmpfolder = os.path.join(cfg['project_path'], 'labeled-data', vname) if os.path.isdir(tmpfolder): print("Frames from video", vname, " already extracted (more will be added)!") else: auxiliaryfunctions.attempttomakefolder(tmpfolder) nframes = np.size(Dataframe.index) print("Loading video...") if opencv: import cv2 cap = cv2.VideoCapture(video) fps = cap.get(5) duration = nframes * 1. / fps size = (int(cap.get(4)), int(cap.get(3))) else: from moviepy.editor import VideoFileClip clip = VideoFileClip(video) fps = clip.fps duration = clip.duration size = clip.size if cfg['cropping']: # one might want to adjust coords = (cfg['x1'], cfg['x2'], cfg['y1'], cfg['y2']) else: coords = None print("Duration of video [s]: ", duration, ", recorded @ ", fps, "fps!") print( "Overall # of frames: ", nframes, "with (cropped) frame dimensions: ", ) if extractionalgorithm == 'uniform': if opencv: frames2pick = frameselectiontools.UniformFramescv2( cap, numframes2extract, start, stop, Index) else: frames2pick = frameselectiontools.UniformFrames( clip, numframes2extract, start, stop, Index) elif extractionalgorithm == 'kmeans': if opencv: frames2pick = frameselectiontools.KmeansbasedFrameselectioncv2( cap, numframes2extract, start, stop, cfg['cropping'], coords, Index, resizewidth=cluster_resizewidth, color=cluster_color) else: if cfg['cropping']: clip = clip.crop(y1=cfg['y1'], y2=cfg['x2'], x1=cfg['x1'], x2=cfg['x2']) frames2pick = frameselectiontools.KmeansbasedFrameselection( clip, numframes2extract, start, stop, Index, resizewidth=cluster_resizewidth, color=cluster_color) else: print( "Please implement this method yourself! Currently the options are 'kmeans', 'jump', 'uniform'." ) frames2pick = [] # Extract frames + frames with plotted labels and store them in folder (with name derived from video name) nder labeled-data print("Let's select frames indices:", frames2pick) colors = visualization.get_cmap(len(bodyparts), cfg['colormap']) strwidth = int(np.ceil(np.log10(nframes))) #width for strings for index in frames2pick: ##tqdm(range(0,nframes,10)): if opencv: PlottingSingleFramecv2(cap, cv2, cfg['cropping'], coords, Dataframe, bodyparts, tmpfolder, index, scorer, cfg['dotsize'], cfg['pcutoff'], cfg['alphavalue'], colors, strwidth, savelabeled) else: PlottingSingleFrame(clip, Dataframe, bodyparts, tmpfolder, index, scorer, cfg['dotsize'], cfg['pcutoff'], cfg['alphavalue'], colors, strwidth, savelabeled) plt.close("all") #close videos if opencv: cap.release() else: clip.close() del clip # Extract annotations based on DeepLabCut and store in the folder (with name derived from video name) under labeled-data if len(frames2pick) > 0: #Dataframe = pd.read_hdf(os.path.join(videofolder,dataname+'.h5')) DF = Dataframe.ix[frames2pick] DF.index = [ os.path.join('labeled-data', vname, "img" + str(index).zfill(strwidth) + ".png") for index in DF.index ] #exchange index number by file names. machinefile = os.path.join( tmpfolder, 'machinelabels-iter' + str(cfg['iteration']) + '.h5') if Path(machinefile).is_file(): Data = pd.read_hdf(machinefile, 'df_with_missing') DataCombined = pd.concat([Data, DF]) #drop duplicate labels: DataCombined = DataCombined[~DataCombined.index.duplicated( keep='first')] DataCombined.to_hdf(machinefile, key='df_with_missing', mode='w') DataCombined.to_csv( os.path.join(tmpfolder, "machinelabels.csv") ) #this is always the most current one (as reading is from h5) else: DF.to_hdf(machinefile, key='df_with_missing', mode='w') DF.to_csv(os.path.join(tmpfolder, "machinelabels.csv")) try: if cfg['cropping']: add.add_new_videos( config, [video], coords=[coords]) # make sure you pass coords as a list else: add.add_new_videos(config, [video], coords=None) except: #can we make a catch here? - in fact we should drop indices from DataCombined if they are in CollectedData.. [ideal behavior; currently this is pretty unlikely] print( "AUTOMATIC ADDING OF VIDEO TO CONFIG FILE FAILED! You need to do this manually for including it in the config.yaml file!" ) print("Videopath:", video, "Coordinates for cropping:", coords) pass print( "The outlier frames are extracted. They are stored in the subdirectory labeled-data\%s." % vname) print( "Once you extracted frames for all videos, use 'refine_labels' to manually correct the labels." ) else: print("No frames were extracted.")
def ExtractFramesbasedonPreselection( Index, extractionalgorithm, data, video, cfg, config, opencv=True, cluster_resizewidth=30, cluster_color=False, savelabeled=True, with_annotations=True, ): from deeplabcut.create_project import add start = cfg["start"] stop = cfg["stop"] numframes2extract = cfg["numframes2pick"] bodyparts = auxiliaryfunctions.IntersectionofBodyPartsandOnesGivenbyUser( cfg, "all") videofolder = str(Path(video).parents[0]) vname = str(Path(video).stem) tmpfolder = os.path.join(cfg["project_path"], "labeled-data", vname) if os.path.isdir(tmpfolder): print("Frames from video", vname, " already extracted (more will be added)!") else: auxiliaryfunctions.attempttomakefolder(tmpfolder, recursive=True) nframes = len(data) print("Loading video...") if opencv: vid = VideoWriter(video) fps = vid.fps duration = vid.calc_duration() else: from moviepy.editor import VideoFileClip clip = VideoFileClip(video) fps = clip.fps duration = clip.duration if cfg["cropping"]: # one might want to adjust coords = (cfg["x1"], cfg["x2"], cfg["y1"], cfg["y2"]) else: coords = None print("Duration of video [s]: ", duration, ", recorded @ ", fps, "fps!") print("Overall # of frames: ", nframes, "with (cropped) frame dimensions: ") if extractionalgorithm == "uniform": if opencv: frames2pick = frameselectiontools.UniformFramescv2( vid, numframes2extract, start, stop, Index) else: frames2pick = frameselectiontools.UniformFrames( clip, numframes2extract, start, stop, Index) elif extractionalgorithm == "kmeans": if opencv: frames2pick = frameselectiontools.KmeansbasedFrameselectioncv2( vid, numframes2extract, start, stop, cfg["cropping"], coords, Index, resizewidth=cluster_resizewidth, color=cluster_color, ) else: if cfg["cropping"]: clip = clip.crop(y1=cfg["y1"], y2=cfg["x2"], x1=cfg["x1"], x2=cfg["x2"]) frames2pick = frameselectiontools.KmeansbasedFrameselection( clip, numframes2extract, start, stop, Index, resizewidth=cluster_resizewidth, color=cluster_color, ) else: print( "Please implement this method yourself! Currently the options are 'kmeans', 'jump', 'uniform'." ) frames2pick = [] # Extract frames + frames with plotted labels and store them in folder (with name derived from video name) nder labeled-data print("Let's select frames indices:", frames2pick) colors = visualization.get_cmap(len(bodyparts), cfg["colormap"]) strwidth = int(np.ceil(np.log10(nframes))) # width for strings for index in frames2pick: ##tqdm(range(0,nframes,10)): if opencv: PlottingSingleFramecv2( vid, cfg["cropping"], coords, data, bodyparts, tmpfolder, index, cfg["dotsize"], cfg["pcutoff"], cfg["alphavalue"], colors, strwidth, savelabeled, ) else: PlottingSingleFrame( clip, data, bodyparts, tmpfolder, index, cfg["dotsize"], cfg["pcutoff"], cfg["alphavalue"], colors, strwidth, savelabeled, ) plt.close("all") # close videos if opencv: vid.close() else: clip.close() del clip # Extract annotations based on DeepLabCut and store in the folder (with name derived from video name) under labeled-data if len(frames2pick) > 0: try: if cfg["cropping"]: add.add_new_videos( config, [video], coords=[coords]) # make sure you pass coords as a list else: add.add_new_videos(config, [video], coords=None) except: # can we make a catch here? - in fact we should drop indices from DataCombined if they are in CollectedData.. [ideal behavior; currently this is pretty unlikely] print( "AUTOMATIC ADDING OF VIDEO TO CONFIG FILE FAILED! You need to do this manually for including it in the config.yaml file!" ) print("Videopath:", video, "Coordinates for cropping:", coords) pass if with_annotations: machinefile = os.path.join( tmpfolder, "machinelabels-iter" + str(cfg["iteration"]) + ".h5") if isinstance(data, pd.DataFrame): df = data.loc[frames2pick] df.index = [ os.path.join( "labeled-data", vname, "img" + str(index).zfill(strwidth) + ".png", ) for index in df.index ] # exchange index number by file names. elif isinstance(data, dict): idx = [ os.path.join( "labeled-data", vname, "img" + str(index).zfill(strwidth) + ".png", ) for index in frames2pick ] filename = os.path.join(str(tmpfolder), f"CollectedData_{cfg['scorer']}.h5") try: df_temp = pd.read_hdf(filename, "df_with_missing") columns = df_temp.columns except FileNotFoundError: columns = pd.MultiIndex.from_product( [ [cfg["scorer"]], cfg["individuals"], cfg["multianimalbodyparts"], ["x", "y"], ], names=["scorer", "individuals", "bodyparts", "coords"], ) if cfg["uniquebodyparts"]: columns2 = pd.MultiIndex.from_product( [ [cfg["scorer"]], ["single"], cfg["uniquebodyparts"], ["x", "y"], ], names=[ "scorer", "individuals", "bodyparts", "coords" ], ) df_temp = pd.concat(( pd.DataFrame(columns=columns), pd.DataFrame(columns=columns2), )) columns = df_temp.columns array = np.full((len(frames2pick), len(columns)), np.nan) for i, index in enumerate(frames2pick): data_temp = data.get(index) if data_temp is not None: vals = np.concatenate(data_temp)[:, :2].flatten() array[i, :len(vals)] = vals df = pd.DataFrame(array, index=idx, columns=columns) else: return if Path(machinefile).is_file(): Data = pd.read_hdf(machinefile, "df_with_missing") DataCombined = pd.concat([Data, df]) # drop duplicate labels: DataCombined = DataCombined[~DataCombined.index.duplicated( keep="first")] DataCombined.to_hdf(machinefile, key="df_with_missing", mode="w") DataCombined.to_csv( os.path.join(tmpfolder, "machinelabels.csv") ) # this is always the most current one (as reading is from h5) else: df.to_hdf(machinefile, key="df_with_missing", mode="w") df.to_csv(os.path.join(tmpfolder, "machinelabels.csv")) print( "The outlier frames are extracted. They are stored in the subdirectory labeled-data\%s." % vname) print( "Once you extracted frames for all videos, use 'refine_labels' to manually correct the labels." ) else: print("No frames were extracted.")
def __init__(self, parent, config, video, shuffle, Dataframe, savelabeled, multianimal): super(MainFrame, self).__init__("DeepLabCut2.0 - Manual Outlier Frame Extraction", parent) ################################################################################################################################################### # Spliting the frame into top and bottom panels. Bottom panels contains the widgets. The top panel is for showing images and plotting! # topSplitter = wx.SplitterWindow(self) # # self.image_panel = ImagePanel(topSplitter, config,video,shuffle,Dataframe,self.gui_size) # self.widget_panel = WidgetPanel(topSplitter) # # topSplitter.SplitHorizontally(self.image_panel, self.widget_panel,sashPosition=self.gui_size[1]*0.83)#0.9 # topSplitter.SetSashGravity(1) # sizer = wx.BoxSizer(wx.VERTICAL) # sizer.Add(topSplitter, 1, wx.EXPAND) # self.SetSizer(sizer) # Spliting the frame into top and bottom panels. Bottom panels contains the widgets. The top panel is for showing images and plotting! topSplitter = wx.SplitterWindow(self) vSplitter = wx.SplitterWindow(topSplitter) self.image_panel = ImagePanel(vSplitter, self.gui_size) self.choice_panel = ScrollPanel(vSplitter) vSplitter.SplitVertically(self.image_panel, self.choice_panel, sashPosition=self.gui_size[0] * 0.8) vSplitter.SetSashGravity(1) self.widget_panel = WidgetPanel(topSplitter) topSplitter.SplitHorizontally(vSplitter, self.widget_panel, sashPosition=self.gui_size[1] * 0.83) # 0.9 topSplitter.SetSashGravity(1) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(topSplitter, 1, wx.EXPAND) self.SetSizer(sizer) ################################################################################################################################################### # Add Buttons to the WidgetPanel and bind them to their respective functions. widgetsizer = wx.WrapSizer(orient=wx.HORIZONTAL) self.load_button_sizer = wx.BoxSizer(wx.VERTICAL) self.help_button_sizer = wx.BoxSizer(wx.VERTICAL) self.help = wx.Button(self.widget_panel, id=wx.ID_ANY, label="Help") self.help_button_sizer.Add(self.help, 1, wx.ALL, 15) # widgetsizer.Add(self.help , 1, wx.ALL, 15) self.help.Bind(wx.EVT_BUTTON, self.helpButton) widgetsizer.Add(self.help_button_sizer, 1, wx.ALL, 0) self.grab = wx.Button(self.widget_panel, id=wx.ID_ANY, label="Grab Frames") widgetsizer.Add(self.grab, 1, wx.ALL, 15) self.grab.Bind(wx.EVT_BUTTON, self.grabFrame) self.grab.Enable(True) widgetsizer.AddStretchSpacer(5) self.slider = wx.Slider( self.widget_panel, id=wx.ID_ANY, value=0, minValue=0, maxValue=1, size=(200, -1), style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS, ) widgetsizer.Add(self.slider, 1, wx.ALL, 5) self.slider.Bind(wx.EVT_SLIDER, self.OnSliderScroll) widgetsizer.AddStretchSpacer(5) self.start_frames_sizer = wx.BoxSizer(wx.VERTICAL) self.end_frames_sizer = wx.BoxSizer(wx.VERTICAL) self.start_frames_sizer.AddSpacer(15) # self.startFrame = wx.SpinCtrl(self.widget_panel, value='0', size=(100, -1), min=0, max=120) self.startFrame = wx.SpinCtrl(self.widget_panel, value="0", size=(100, -1)) # ,style=wx.SP_VERTICAL) self.startFrame.Enable(False) self.start_frames_sizer.Add(self.startFrame, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) start_text = wx.StaticText(self.widget_panel, label="Start Frame Index") self.start_frames_sizer.Add(start_text, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) self.checkBox = wx.CheckBox(self.widget_panel, id=wx.ID_ANY, label="Range of frames") self.checkBox.Bind(wx.EVT_CHECKBOX, self.activate_frame_range) self.start_frames_sizer.Add(self.checkBox, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) # self.end_frames_sizer.AddSpacer(15) self.endFrame = wx.SpinCtrl(self.widget_panel, value="1", size=(160, -1)) # , min=1, max=120) self.endFrame.Enable(False) self.end_frames_sizer.Add(self.endFrame, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) end_text = wx.StaticText(self.widget_panel, label="Number of Frames") self.end_frames_sizer.Add(end_text, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) self.updateFrame = wx.Button(self.widget_panel, id=wx.ID_ANY, label="Update") self.end_frames_sizer.Add(self.updateFrame, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) self.updateFrame.Bind(wx.EVT_BUTTON, self.updateSlider) self.updateFrame.Enable(False) widgetsizer.Add(self.start_frames_sizer, 1, wx.ALL, 0) widgetsizer.AddStretchSpacer(5) widgetsizer.Add(self.end_frames_sizer, 1, wx.ALL, 0) widgetsizer.AddStretchSpacer(15) self.quit = wx.Button(self.widget_panel, id=wx.ID_ANY, label="Quit") widgetsizer.Add(self.quit, 1, wx.ALL, 15) self.quit.Bind(wx.EVT_BUTTON, self.quitButton) self.quit.Enable(True) self.widget_panel.SetSizer(widgetsizer) self.widget_panel.SetSizerAndFit(widgetsizer) # Variables initialization self.numberFrames = 0 self.currFrame = 0 self.figure = Figure() self.axes = self.figure.add_subplot(111) self.drs = [] self.extract_range_frame = False self.firstFrame = 0 self.Colorscheme = [] # Read confing file self.cfg = auxiliaryfunctions.read_config(config) self.Task = self.cfg["Task"] self.start = self.cfg["start"] self.stop = self.cfg["stop"] self.date = self.cfg["date"] self.trainFraction = self.cfg["TrainingFraction"] self.trainFraction = self.trainFraction[0] self.videos = self.cfg["video_sets"].keys() self.bodyparts = self.cfg["bodyparts"] self.colormap = plt.get_cmap(self.cfg["colormap"]) self.colormap = self.colormap.reversed() self.markerSize = self.cfg["dotsize"] self.alpha = self.cfg["alphavalue"] self.iterationindex = self.cfg["iteration"] self.cropping = self.cfg["cropping"] self.video_names = [Path(i).stem for i in self.videos] self.config_path = Path(config) self.video_source = Path(video).resolve() self.shuffle = shuffle self.Dataframe = Dataframe self.savelabeled = savelabeled self.multianimal = multianimal if self.multianimal: from deeplabcut.utils import auxfun_multianimal ( self.individual_names, self.uniquebodyparts, self.multianimalbodyparts, ) = auxfun_multianimal.extractindividualsandbodyparts(self.cfg) self.choiceBox, self.visualization_rdb = self.choice_panel.addRadioButtons( ) self.Colorscheme = visualization.get_cmap( len(self.individual_names), self.cfg["colormap"]) self.visualization_rdb.Bind(wx.EVT_RADIOBOX, self.clear_plot) # Read the video file self.vid = VideoWriter(str(self.video_source)) if self.cropping: self.vid.set_bbox(self.cfg["x1"], self.cfg["x2"], self.cfg["y1"], self.cfg["y2"]) self.filename = Path(self.video_source).name self.numberFrames = len(self.vid) self.strwidth = int(np.ceil(np.log10(self.numberFrames))) # Set the values of slider and range of frames self.startFrame.SetMax(self.numberFrames - 1) self.slider.SetMax(self.numberFrames - 1) self.endFrame.SetMax(self.numberFrames - 1) self.startFrame.Bind(wx.EVT_SPINCTRL, self.updateSlider) # wx.EVT_SPIN # Set the status bar self.statusbar.SetStatusText("Working on video: {}".format( self.filename)) # Adding the video file to the config file. if self.vid.name not in self.video_names: add.add_new_videos(self.config_path, [self.video_source]) self.update() self.plot_labels() self.widget_panel.Layout()
def __init__(self, parent, config, video, shuffle, Dataframe, savelabeled, multianimal): # Settting the GUI size and panels design displays = (wx.Display(i) for i in range(wx.Display.GetCount()) ) # Gets the number of displays screenSizes = [ display.GetGeometry().GetSize() for display in displays ] # Gets the size of each display index = 0 # For display 1. screenWidth = screenSizes[index][0] screenHeight = screenSizes[index][1] self.gui_size = (screenWidth * 0.7, screenHeight * 0.85) wx.Frame.__init__( self, parent, id=wx.ID_ANY, title="DeepLabCut2.0 - Manual Outlier Frame Extraction", size=wx.Size(self.gui_size), pos=wx.DefaultPosition, style=wx.RESIZE_BORDER | wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL, ) self.statusbar = self.CreateStatusBar() self.statusbar.SetStatusText("") self.SetSizeHints( wx.Size(self.gui_size) ) # This sets the minimum size of the GUI. It can scale now! ################################################################################################################################################### # Spliting the frame into top and bottom panels. Bottom panels contains the widgets. The top panel is for showing images and plotting! # topSplitter = wx.SplitterWindow(self) # # self.image_panel = ImagePanel(topSplitter, config,video,shuffle,Dataframe,self.gui_size) # self.widget_panel = WidgetPanel(topSplitter) # # topSplitter.SplitHorizontally(self.image_panel, self.widget_panel,sashPosition=self.gui_size[1]*0.83)#0.9 # topSplitter.SetSashGravity(1) # sizer = wx.BoxSizer(wx.VERTICAL) # sizer.Add(topSplitter, 1, wx.EXPAND) # self.SetSizer(sizer) # Spliting the frame into top and bottom panels. Bottom panels contains the widgets. The top panel is for showing images and plotting! topSplitter = wx.SplitterWindow(self) vSplitter = wx.SplitterWindow(topSplitter) self.image_panel = ImagePanel(vSplitter, self.gui_size) self.choice_panel = ScrollPanel(vSplitter) vSplitter.SplitVertically(self.image_panel, self.choice_panel, sashPosition=self.gui_size[0] * 0.8) vSplitter.SetSashGravity(1) self.widget_panel = WidgetPanel(topSplitter) topSplitter.SplitHorizontally(vSplitter, self.widget_panel, sashPosition=self.gui_size[1] * 0.83) # 0.9 topSplitter.SetSashGravity(1) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(topSplitter, 1, wx.EXPAND) self.SetSizer(sizer) ################################################################################################################################################### # Add Buttons to the WidgetPanel and bind them to their respective functions. widgetsizer = wx.WrapSizer(orient=wx.HORIZONTAL) self.load_button_sizer = wx.BoxSizer(wx.VERTICAL) self.help_button_sizer = wx.BoxSizer(wx.VERTICAL) self.help = wx.Button(self.widget_panel, id=wx.ID_ANY, label="Help") self.help_button_sizer.Add(self.help, 1, wx.ALL, 15) # widgetsizer.Add(self.help , 1, wx.ALL, 15) self.help.Bind(wx.EVT_BUTTON, self.helpButton) widgetsizer.Add(self.help_button_sizer, 1, wx.ALL, 0) self.grab = wx.Button(self.widget_panel, id=wx.ID_ANY, label="Grab Frames") widgetsizer.Add(self.grab, 1, wx.ALL, 15) self.grab.Bind(wx.EVT_BUTTON, self.grabFrame) self.grab.Enable(True) widgetsizer.AddStretchSpacer(5) self.slider = wx.Slider( self.widget_panel, id=wx.ID_ANY, value=0, minValue=0, maxValue=1, size=(200, -1), style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS, ) widgetsizer.Add(self.slider, 1, wx.ALL, 5) self.slider.Bind(wx.EVT_SLIDER, self.OnSliderScroll) widgetsizer.AddStretchSpacer(5) self.start_frames_sizer = wx.BoxSizer(wx.VERTICAL) self.end_frames_sizer = wx.BoxSizer(wx.VERTICAL) self.start_frames_sizer.AddSpacer(15) # self.startFrame = wx.SpinCtrl(self.widget_panel, value='0', size=(100, -1), min=0, max=120) self.startFrame = wx.SpinCtrl(self.widget_panel, value="0", size=(100, -1)) # ,style=wx.SP_VERTICAL) self.startFrame.Enable(False) self.start_frames_sizer.Add(self.startFrame, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) start_text = wx.StaticText(self.widget_panel, label="Start Frame Index") self.start_frames_sizer.Add(start_text, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) self.checkBox = wx.CheckBox(self.widget_panel, id=wx.ID_ANY, label="Range of frames") self.checkBox.Bind(wx.EVT_CHECKBOX, self.activate_frame_range) self.start_frames_sizer.Add(self.checkBox, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) # self.end_frames_sizer.AddSpacer(15) self.endFrame = wx.SpinCtrl(self.widget_panel, value="1", size=(160, -1)) # , min=1, max=120) self.endFrame.Enable(False) self.end_frames_sizer.Add(self.endFrame, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) end_text = wx.StaticText(self.widget_panel, label="Number of Frames") self.end_frames_sizer.Add(end_text, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) self.updateFrame = wx.Button(self.widget_panel, id=wx.ID_ANY, label="Update") self.end_frames_sizer.Add(self.updateFrame, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) self.updateFrame.Bind(wx.EVT_BUTTON, self.updateSlider) self.updateFrame.Enable(False) widgetsizer.Add(self.start_frames_sizer, 1, wx.ALL, 0) widgetsizer.AddStretchSpacer(5) widgetsizer.Add(self.end_frames_sizer, 1, wx.ALL, 0) widgetsizer.AddStretchSpacer(15) self.quit = wx.Button(self.widget_panel, id=wx.ID_ANY, label="Quit") widgetsizer.Add(self.quit, 1, wx.ALL, 15) self.quit.Bind(wx.EVT_BUTTON, self.quitButton) self.quit.Enable(True) self.widget_panel.SetSizer(widgetsizer) self.widget_panel.SetSizerAndFit(widgetsizer) # Variables initialization self.numberFrames = 0 self.currFrame = 0 self.figure = Figure() self.axes = self.figure.add_subplot(111) self.drs = [] self.extract_range_frame = False self.firstFrame = 0 self.Colorscheme = [] # self.cropping = False # Read confing file self.cfg = auxiliaryfunctions.read_config(config) self.Task = self.cfg["Task"] self.start = self.cfg["start"] self.stop = self.cfg["stop"] self.date = self.cfg["date"] self.trainFraction = self.cfg["TrainingFraction"] self.trainFraction = self.trainFraction[0] self.videos = self.cfg["video_sets"].keys() self.bodyparts = self.cfg["bodyparts"] self.colormap = plt.get_cmap(self.cfg["colormap"]) self.colormap = self.colormap.reversed() self.markerSize = self.cfg["dotsize"] self.alpha = self.cfg["alphavalue"] self.iterationindex = self.cfg["iteration"] self.cropping = self.cfg["cropping"] self.video_names = [Path(i).stem for i in self.videos] self.config_path = Path(config) self.video_source = Path(video).resolve() self.shuffle = shuffle self.Dataframe = Dataframe self.savelabeled = savelabeled self.multianimal = multianimal if self.multianimal: from deeplabcut.utils import auxfun_multianimal ( self.individual_names, self.uniquebodyparts, self.multianimalbodyparts, ) = auxfun_multianimal.extractindividualsandbodyparts(self.cfg) self.choiceBox, self.visualization_rdb = self.choice_panel.addRadioButtons( ) self.Colorscheme = visualization.get_cmap( len(self.individual_names), self.cfg["colormap"]) self.visualization_rdb.Bind(wx.EVT_RADIOBOX, self.clear_plot) # Read the video file self.vid = cv2.VideoCapture(str(self.video_source)) self.videoPath = os.path.dirname(self.video_source) self.filename = Path(self.video_source).name self.numberFrames = int(self.vid.get(cv2.CAP_PROP_FRAME_COUNT)) self.strwidth = int(np.ceil(np.log10(self.numberFrames))) # Set the values of slider and range of frames self.startFrame.SetMax(self.numberFrames - 1) self.slider.SetMax(self.numberFrames - 1) self.endFrame.SetMax(self.numberFrames - 1) self.startFrame.Bind(wx.EVT_SPINCTRL, self.updateSlider) # wx.EVT_SPIN # Set the status bar self.statusbar.SetStatusText("Working on video: {}".format( os.path.split(str(self.video_source))[-1])) # Adding the video file to the config file. if not (str(self.video_source.stem) in self.video_names): add.add_new_videos(self.config_path, [self.video_source]) self.filename = Path(self.video_source).name self.update() self.plot_labels() self.widget_panel.Layout()
def __init__(self, parent, config, video, shuffle, Dataframe, scorer, savelabeled): # Settting the GUI size and panels design displays = (wx.Display(i) for i in range(wx.Display.GetCount()) ) # Gets the number of displays screenSizes = [ display.GetGeometry().GetSize() for display in displays ] # Gets the size of each display index = 0 # For display 1. screenWidth = screenSizes[index][0] screenHeight = screenSizes[index][1] self.gui_size = (screenWidth * 0.7, screenHeight * 0.85) wx.Frame.__init__( self, parent, id=wx.ID_ANY, title='DeepLabCut2.0 - Manual Outlier Frame Extraction', size=wx.Size(self.gui_size), pos=wx.DefaultPosition, style=wx.RESIZE_BORDER | wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL) self.statusbar = self.CreateStatusBar() self.statusbar.SetStatusText("") self.SetSizeHints( wx.Size(self.gui_size) ) # This sets the minimum size of the GUI. It can scale now! ################################################################################################################################################### # Spliting the frame into top and bottom panels. Bottom panels contains the widgets. The top panel is for showing images and plotting! topSplitter = wx.SplitterWindow(self) self.image_panel = ImagePanel(topSplitter, config, video, shuffle, Dataframe, self.gui_size) self.widget_panel = WidgetPanel(topSplitter) topSplitter.SplitHorizontally(self.image_panel, self.widget_panel, sashPosition=self.gui_size[1] * 0.83) #0.9 topSplitter.SetSashGravity(1) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(topSplitter, 1, wx.EXPAND) self.SetSizer(sizer) ################################################################################################################################################### # Add Buttons to the WidgetPanel and bind them to their respective functions. widgetsizer = wx.WrapSizer(orient=wx.HORIZONTAL) self.load_button_sizer = wx.BoxSizer(wx.VERTICAL) self.help_button_sizer = wx.BoxSizer(wx.VERTICAL) self.help = wx.Button(self.widget_panel, id=wx.ID_ANY, label="Help") self.help_button_sizer.Add(self.help, 1, wx.ALL, 15) # widgetsizer.Add(self.help , 1, wx.ALL, 15) self.help.Bind(wx.EVT_BUTTON, self.helpButton) widgetsizer.Add(self.help_button_sizer, 1, wx.ALL, 0) self.grab = wx.Button(self.widget_panel, id=wx.ID_ANY, label="Grab Frames") widgetsizer.Add(self.grab, 1, wx.ALL, 15) self.grab.Bind(wx.EVT_BUTTON, self.grabFrame) self.grab.Enable(True) widgetsizer.AddStretchSpacer(5) self.slider = wx.Slider(self.widget_panel, id=wx.ID_ANY, value=0, minValue=0, maxValue=1, size=(200, -1), style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | wx.SL_LABELS) widgetsizer.Add(self.slider, 1, wx.ALL, 5) self.slider.Bind(wx.EVT_SLIDER, self.OnSliderScroll) widgetsizer.AddStretchSpacer(5) self.start_frames_sizer = wx.BoxSizer(wx.VERTICAL) self.end_frames_sizer = wx.BoxSizer(wx.VERTICAL) self.start_frames_sizer.AddSpacer(15) # self.startFrame = wx.SpinCtrl(self.widget_panel, value='0', size=(100, -1), min=0, max=120) self.startFrame = wx.SpinCtrl(self.widget_panel, value='0', size=(100, -1)) #,style=wx.SP_VERTICAL) self.startFrame.Enable(False) self.start_frames_sizer.Add(self.startFrame, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) start_text = wx.StaticText(self.widget_panel, label='Start Frame Index') self.start_frames_sizer.Add(start_text, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) self.checkBox = wx.CheckBox(self.widget_panel, id=wx.ID_ANY, label='Range of frames') self.checkBox.Bind(wx.EVT_CHECKBOX, self.activate_frame_range) self.start_frames_sizer.Add(self.checkBox, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) # self.end_frames_sizer.AddSpacer(15) self.endFrame = wx.SpinCtrl(self.widget_panel, value='1', size=(160, -1)) #, min=1, max=120) self.endFrame.Enable(False) self.end_frames_sizer.Add(self.endFrame, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) end_text = wx.StaticText(self.widget_panel, label='Number of Frames') self.end_frames_sizer.Add(end_text, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) self.updateFrame = wx.Button(self.widget_panel, id=wx.ID_ANY, label="Update") self.end_frames_sizer.Add(self.updateFrame, 1, wx.EXPAND | wx.ALIGN_LEFT, 15) self.updateFrame.Bind(wx.EVT_BUTTON, self.updateSlider) self.updateFrame.Enable(False) widgetsizer.Add(self.start_frames_sizer, 1, wx.ALL, 0) widgetsizer.AddStretchSpacer(5) widgetsizer.Add(self.end_frames_sizer, 1, wx.ALL, 0) widgetsizer.AddStretchSpacer(15) self.quit = wx.Button(self.widget_panel, id=wx.ID_ANY, label="Quit") widgetsizer.Add(self.quit, 1, wx.ALL, 15) self.quit.Bind(wx.EVT_BUTTON, self.quitButton) self.quit.Enable(True) self.widget_panel.SetSizer(widgetsizer) self.widget_panel.SetSizerAndFit(widgetsizer) # Variables initialization self.numberFrames = 0 self.currFrame = 0 self.figure = Figure() self.axes = self.figure.add_subplot(111) self.drs = [] self.extract_range_frame = False self.firstFrame = 0 # self.cropping = False # Read confing file self.cfg = auxiliaryfunctions.read_config(config) self.Task = self.cfg['Task'] self.start = self.cfg['start'] self.stop = self.cfg['stop'] self.date = self.cfg['date'] self.trainFraction = self.cfg['TrainingFraction'] self.trainFraction = self.trainFraction[0] self.videos = self.cfg['video_sets'].keys() self.bodyparts = self.cfg['bodyparts'] self.colormap = plt.get_cmap(self.cfg['colormap']) self.colormap = self.colormap.reversed() self.markerSize = self.cfg['dotsize'] self.alpha = self.cfg['alphavalue'] self.iterationindex = self.cfg['iteration'] self.cropping = self.cfg['cropping'] self.video_names = [Path(i).stem for i in self.videos] self.config_path = Path(config) self.video_source = Path(video).resolve() self.shuffle = shuffle self.Dataframe = Dataframe self.scorer = scorer self.savelabeled = savelabeled # Read the video file self.vid = FMF.FlyMovie(str(self.video_source)) self.videoPath = os.path.dirname(self.video_source) self.filename = Path(self.video_source).name nframes = self.vid.n_frames while True: try: self.vid.get_frame(nframes) except FMF.NoMoreFramesException: nframes -= 1 continue break self.numberFrames = int(nframes) self.strwidth = int(np.ceil(np.log10(self.numberFrames))) # Set the values of slider and range of frames self.startFrame.SetMax(self.numberFrames - 1) self.slider.SetMax(self.numberFrames - 1) self.endFrame.SetMax(self.numberFrames - 1) self.startFrame.Bind(wx.EVT_SPINCTRL, self.updateSlider) #wx.EVT_SPIN # Set the status bar self.statusbar.SetStatusText('Working on video: {}'.format( os.path.split(str(self.video_source))[-1])) # Adding the video file to the config file. if not (str(self.video_source.stem) in self.video_names): add.add_new_videos(self.config_path, [self.video_source]) self.filename = Path(self.video_source).name self.update() self.plot_labels() self.widget_panel.Layout()