def __init__(self): super(Example1, self).__init__('dir examples') self.parent = None self._directory = ControlDir('Choose a directory') self._file = ControlFile('Choose a file') self._filetree = ControlFilesTree('Choose a file') self._image = ControlImage('Image') self._boundaries = ControlBoundingSlider('Bounding', horizontal=True) self._button = ControlButton('Click') self._button.value = self.onButtonClick # self._directory.value=self.onButtonClick self._checkbox = ControlCheckBox('Choose a directory') self._checkboxList = ControlCheckBoxList('Choose a file') self._player = ControlPlayer('Choose a file') self._slider = ControlSlider('Slider') self._player.show() self._checkboxList.value = [('Item 1', True), ('Item 2', False), ('Item 3', True)] self._combobox = ControlCombo('Choose a item') self._list = ControlList('List label') self._progress = ControlProgress('Progress bar') self._visvisVolume = ControlVisVisVolume('Visvis') self._timeline = ControlEventTimeline('Timeline') self._combobox.add_item('Item 1', 'Value 1') self._combobox.add_item('Item 2', 'Value 2') self._combobox.add_item('Item 3', 'Value 3') self._combobox.add_item('Item 4') self._list.value = [('Item1', 'Item2', 'Item3',), ('Item3', 'Item4', 'Item5',)] imageWithVolume = np.zeros((100, 100, 100), np.uint8) imageWithVolume[30:40, 30:50, :] = 255 imageWithVolume[30:40, 70:72, :] = 255 self._visvisVolume.value = imageWithVolume self._visvis = ControlVisVis('Visvis') values1 = [(i, random.random(), random.random()) for i in range(130)] values2 = [(i, random.random(), random.random()) for i in range(130)] self._visvis.value = [values1, values2] self.formset = [ '_visvis' , '_directory' , '_button' , '_file' , '_boundaries' , '_filetree' , '_image' , '_slider' , ('_checkboxList', '_player') , ('_checkbox', ' ') , ('_combobox', ' ') , '_progress' , '=' , ('_visvisVolume', '||', '_list') , '_timeline' ]
def __init__(self, parent=None): BaseWidget.__init__(self, 'Motion counter', parent_win=parent) self.set_margin(5) self.setMinimumHeight(300) self.setMinimumWidth(500) self._player = ControlPlayer('Player') self._datasets = ControlEmptyWidget('Paths', default=DatasetsDialog()) self._backgrounds = ControlEmptyWidget('Backgrounds', default=ObjectsDialog()) self._show_diff = ControlCheckBox('Show diffs boxes') self._threshold = ControlSlider('Threshold', default=5, minimum=1, maximum=255) self._radius = ControlSlider('Radius', default=30, minimum=1, maximum=200) self._apply = ControlButton('Apply', checkable=True) self._compare = ControlCombo('Compare with') self._progress = ControlProgress('Progress') self._formset = [ '_datasets', '=', '_compare', '_backgrounds', ('_threshold', '_radius', '_show_diff'), '_player', '_apply', '_progress' ] self._compare.add_item('Last frame', 1) self._compare.add_item('First frame', 2) self._compare.add_item('Background image', 3) self.load_order = ['_threshold', '_radius', '_show_diff'] self._backgrounds.value.datasets_filter = lambda x: isinstance( x, Image) self._datasets.value.datasets_filter = lambda x: isinstance( x, (Contours, Path)) self._player.process_frame_event = self.__process_frame_event self._datasets.value.video_selection_changed_event = self.__video_selection_changed_event self._compare.changed_event = self.__compare_changed_event self._apply.value = self.__apply_btn_event self._apply.icon = conf.ANNOTATOR_ICON_MOTION self._progress.hide() self._backgrounds.hide()
def __init__(self, *args, **kwargs): super().__init__('4-Cam') self.set_margin(10) # Definition of the forms fields self._player1 = ControlPlayer('Player1') self._player2 = ControlPlayer('Player2') self._player3 = ControlPlayer('Player3') self._player4 = ControlPlayer('Player4') self._runbutton = ControlButton('Stop') self._screenshot = ControlButton('Screenshot') self._outputfile = ControlDir('Screenshots Ausgabe Ordner') self._cams = ControlCheckBoxList('Kameras') # Define the event that will be called when the run button is processed self._runbutton.value = self.__stopEvent self._screenshot.value = self._saveImages self.__check_all_avaliable_cameras() self.formset = [{ '0-Kameras': [('_runbutton'), ('_player1', '_player2'), ('_player3', '_player4')], '1-Einstellungen': [('_outputfile'), ('_cams')] }] self._player1.value = self.__assign_capture(0) self._player2.value = self.__assign_capture(1) self._player3.value = self.__assign_capture(2) self._player4.value = self.__assign_capture(3) self._outputfile.value = os.getcwd() self.__runEvent()
def __init__(self, parent=None, video=None): BaseWidget.__init__(self, 'Simple workflow editor', parent_win=parent) self._parent = parent self._player = ControlPlayer('Player') self._imgfilters = ControlList('Image filters') self._imageflows = ControlCombo('Image workflows') self._blobsflows = ControlCombo('Blobs workflows') self._blobsfilters = ControlList('Blobs filters') self.formset = [ '_player', '=', [{ 'a:Image filter': ['_imageflows', '_imgfilters'], 'b:Blobs filter': ['_blobsflows', '_blobsfilters'] }] ] self.load_order = [ '_imageflows', '_blobsflows', '_imgfilters', '_blobsfilters' ] self._imgfilters.select_entire_row = True self._blobsfilters.select_entire_row = True self._imageflows.changed_event = self.__imageflows_changed_event self._blobsflows.changed_event = self.__blobsflows_changed_event self._player.process_frame_event = self.__process_frame self.video_capture = video self._pipelines = {} # dictinary with all the available pipelines self._pipeline = None # active pipeline class
def __init__(self): BaseWidget.__init__(self, 'Video window') self._player = ControlPlayer('Player') self.formset = ['_player']
def __init__(self, parent=None): super(GeometryFromThreshold, self).__init__('Find geometry using a threshold on the image', parent_win=parent) self._filename = ControlFile('Video file name') self._player = ControlPlayer('Player') self._threshold = ControlSlider('Movement threshold', default=10, minimum=0, maximum=255) self._epsilon = ControlSlider('Epsilon', default=10, minimum=1, maximum=255) self._add_contour = ControlButton('add contour') self._formset = [ '_filename', ('_threshold', '_epsilon', '_add_contour'), '_player' ] self._filename.changed_event = self.__filename_changed self._player.process_frame_event = self.__processFrame self._threshold.changed_event = self._player.refresh self._epsilon.changed_event = self._player.refresh self._add_contour.value = self.__add_contours self._filename.value = '/home/ricardo/bitbucket/single-fly-tracker/Circle_and_Square.avi' self._contours = []
def __init__(self, name): icon_path = tools.getFileInSameDirectory(__file__, 'iconsubbg.jpg') TypeColorVideoPipe.__init__(self) OTModulePlugin.__init__(self, name, iconFile=icon_path) self._video = ModuleConnection("Video", connecting=TypeColorVideo) self._player = ControlPlayer("Video player") self._colorDomain = ControlCombo("Color domain") self._colorDomain.addItem("XYZ", cv2.COLOR_BGR2XYZ) self._colorDomain.addItem("YCrCb", cv2.COLOR_BGR2YCR_CB) self._colorDomain.addItem("HSV", cv2.COLOR_BGR2HSV) self._colorDomain.addItem("HLS", cv2.COLOR_BGR2HLS) self._colorDomain.addItem("Lab", cv2.COLOR_BGR2LAB) self._colorDomain.addItem("Luv", cv2.COLOR_BGR2LUV) self._colorDomain.changed = self._player.refresh self._video.changed = self.newVideoInputChoosen self._player.processFrame = self.processFrame self._formset = [ '_video', '_colorDomain', "_player", ]
def __init__(self, *args, **kwargs): super().__init__('Computer vision algorithm example') #Definition of the forms fields self._videofile = ControlFile('Video') self._outputfile = ControlText('Results output file') self._threshold = ControlSlider('Threshold', default=114, minimum=0, maximum=255) self._blobsize = ControlSlider('Minimum blob size', default=110, minimum=100, maximum=2000) self._player = ControlPlayer('Player') self._runbutton = ControlButton('Run') #Define the function that will be called when a file is selected self._videofile.changed_event = self.__video_file_selection_event #Define the event that will be called when the run button is processed self._runbutton.value = self.run_event #Define the event called before showing the image in the player self._player.process_frame_event = self.__process_frame #Define the organization of the Form Controls self._formset = [('_videofile', '_outputfile'), '_threshold', ('_blobsize', '_runbutton'), '_player']
def __init__(self): global conf conf += 'pythonvideoannotator.resources' # Resources can only be loaded after pyqt is running super(BaseModule, self).__init__('Video annotation editor') self._project = Project(parent=self) Dialog.project = self._project self._player = ControlPlayer("Player") self._time = ControlEventTimeline('Time') self._dock = ControlDockWidget("Timeline", side='bottom', order=1, margin=5) self.formset = ['_player'] self._dock.value = self._time self._player.process_frame_event = self.process_frame_event self._player.click_event = self.on_player_click_event self._time.key_release_event = self.__timeline_key_release_event self.load_order = [] self.mainmenu.insert( 0, { 'File': [{ 'Open': self.__open_project_event, 'icon': conf.ANNOTATOR_ICON_OPEN }, '-', { 'Save': self.__save_project_event, 'icon': conf.ANNOTATOR_ICON_SAVE }, { 'Save as': self.__save_project_as_event, 'icon': conf.ANNOTATOR_ICON_SAVE }, '-', { 'Exit': QApplication.closeAllWindows, 'icon': conf.ANNOTATOR_ICON_EXIT }] }) self.mainmenu.insert(1, {'Modules': []}) self.mainmenu.insert(2, {'Windows': []}) track_user_stats()
def __init__(self): BaseWidget.__init__(self, 'Batch Object Detection') self.batchFolder = "" self.batchFile = "" self._dir = ControlFile() self.Canvas = ControlPlayer('Canvas') self._label1 = ControlLabel("") self._start = ControlButton("Count") self._clr = ControlButton("Clear count") self._Progress = ControlProgress(label="0/0") self._Progress.min = 0 self._clr.value = self.clr_mongo self.Canvas.value = "./batchDetect/test.jpg" self._dir.changed_event = self.folderpath_event self._start.value = self._startCount
def __init__(self, title, parent=None): super(GeometryManualDesigner, self).__init__(title, parent_win=parent) self._threshold_win = None self._start_point = None self._end_point = None self._selected_poly = None self._selected_point = None self._video = ControlFile("Video file") self._player = ControlPlayer("Video") self._remove = ControlButton("Remove") self._square = ControlButton("Square", checkable=True) self._circle = ControlButton("Circle", checkable=True) self._threshold = ControlButton("Threshold") self._export = ControlButton("Export") self._import = ControlButton("Import") self._polygons = ControlList('Polygons') self._apply = ControlButton('Apply') self._formset = [ '_video', "_player", ("_square", "_circle", "_threshold", " ", "_remove", " ", "_export", "_import"), "=", "_polygons", '_apply' ] self._video.changedchanged_event = self.videoSelected self._square.value = self.square_toggle self._circle.value = self.circle_toggle self._remove.value = self.remove_clicked self._export.value = self.export_clicked self._import.value = self.import_clicked self._threshold.value = self.threshold_btn_click self._player.drag_event = self.on_player_drag_in_video_window self._player.end_drag_event = self.on_player_end_drag_in_video_window self._player.click_event = self.on_player_click_in_video_window self._player.double_click_event = self.on_player_double_click_in_video_window self._player.process_frame_event = self.process_frame self._player.key_release_event = self.on_player_key_release self._apply.hide()
def __init__(self, name): OTModulePlugin.__init__(self, name, iconFile = tools.getFileInSameDirectory(__file__, 'iconvi.jpg')) TypeColorVideo.__init__(self) self._file = ControlFile("File") self._player = ControlPlayer("Video") self._formset = [ "_file", "_player"] self._file.changed = self.__videoSelected
def __init__(self, name): icon_path = tools.getFileInSameDirectory(__file__, 'iconsubbg.jpg') TypeBWVideoPipe.__init__(self) OTModulePlugin.__init__(self, name, iconFile=icon_path) self._video = ModuleConnection("Video", connecting=TypeComponentsVideoPipe) self._player = ControlPlayer("Video player") self._colorComponent = ControlCombo("Component") self._colorComponent.addItem("A", 0) self._colorComponent.addItem("B", 1) self._colorComponent.addItem("C", 2) self._colorComponent.valueUpdated = self.refreshValue self._video.changed = self.newVideoInputChoosen self._formset = [ '_video', '_colorComponent', "_player", ]
class OTModuleSelectComponent(OTModulePlugin,TypeBWVideoPipe): def __init__(self, name): icon_path = tools.getFileInSameDirectory(__file__, 'iconsubbg.jpg') TypeBWVideoPipe.__init__(self) OTModulePlugin.__init__(self, name, iconFile=icon_path) self._video = ModuleConnection("Video", connecting=TypeComponentsVideoPipe) self._player = ControlPlayer("Video player") self._colorComponent = ControlCombo("Component") self._colorComponent.addItem("A", 0) self._colorComponent.addItem("B", 1) self._colorComponent.addItem("C", 2) self._colorComponent.valueUpdated = self.refreshValue self._video.changed = self.newVideoInputChoosen self._formset = [ '_video', '_colorComponent', "_player", ] def refreshValue(self, value): self._player.refresh() def newVideoInputChoosen(self): ModuleConnection.changed(self._video) value = self._video.value if value: self.open(value) self._player.value = self print value def read(self): res, imgs = self._video.value.read() return res, imgs[self._colorComponent.value]
def __init__(self): super(VideoPlayer, self).__init__('Video Player') #Defnition of the form fields # self._dirname = ControlText('Directory', 'Default Value') self._button_play = ControlButton("Play") self._button_play.value = self.__play_all self._button_pause = ControlButton("Pause") self._button_pause.value = self.__pause_all self._button_refresh = ControlButton("Reload") self._button_refresh.value = self.__refresh_all self._button_print = ControlButton("Print") self._button_print.value = self.__print_value # self.formset = [{'Tab1':['_dirname'],},'_button'] # self._directory = ControlDir('Choose a directory') self._file1 = ControlFile('File 1') self._file2 = ControlFile('File 2') # print(self._file.value) self._filetree = ControlFilesTree('Choose a file') # self._filetree.value = 'C:\\Users\\Ashwini Naik\\Videos\\Captures' # self._checkbox = ControlCheckBox('Choose a directory') # self._checkboxList = ControlCheckBoxList('Choose a file') self._player = ControlPlayer('Choose a file') self._player1 = ControlPlayer('Choose a file') # self._slider = ControlSlider('Slider') self._player.value = '_file.value' # self._player.refresh() self.formset = [('_button_play', '_button_pause', '_button_refresh'), ('_file1', '_file2'), ('_player', '_player1')]
def __init__(self, name): icon_path = tools.getFileInSameDirectory(__file__, 'iconsubbg.jpg') OTModulePlugin.__init__(self, name, iconFile=icon_path) TypeComponentsVideoPipe.__init__(self) self._video = ModuleConnection("Video", connecting=TypeColorVideo) self._player = ControlPlayer("Video player") self._player.processFrame = self.processFrame self._video.changed = self.newVideoInputChoosen self._formset = [ '_video', "_player", ]
def __init__(self, *args, **kwargs): super().__init__('Pixie') tempath = "" #mainMenu self.mainmenu = [{ 'File': [{ 'Open': self.__openEvent }, '-', { 'Save': self.__saveEvent }] }] #definition toolsBox = ToolsBox() toolsBox.parent = self self._dockleft = ControlDockWidget() self._dockleft.value = toolsBox self._imglabel = ControlLabel() self._ControlImage = ControlPlayer('canvas') self._ToolsBox__updateImage("") self._detail = ControlLabel('Detail')
def __init__(self, name): icon_path = tools.getFileInSameDirectory(__file__, 'iconsubbg.jpg') OTModulePlugin.__init__(self, name, iconFile=icon_path) TypeSingleChannelImage.__init__(self) self._video = ModuleConnection("Video", connecting=TypeBWVideoPipe) self._player = ControlPlayer("Video player") self._min = ControlSlider("Min", default=1, minimum=0, maximum=255) self._max = ControlSlider("Max", default=255, minimum=0, maximum=255) self._formset = [ '_video', "_player", '_min', '_max' ] self._player.processFrame = self.processFrame self._video.changed = self.newVideoInputChoosen self._min.changed = self._player.refresh self._max.changed = self._player.refresh
def __init__(self): super(MultipleBlobDetection, self).__init__('Multiple Blob Detection') # Definition of the forms fields self._videofile = ControlFile('Video') self._outputfile = ControlText('Results output file') self._threshold_box = ControlCheckBox('Threshold') self._threshold = ControlSlider('Binary Threshold') self._threshold.value = 114 self._threshold.min = 1 self._threshold.max = 255 self._roi_x_min = ControlSlider('ROI x top') self._roi_x_max = ControlSlider('ROI x bottom') self._roi_y_min = ControlSlider('ROI y left') self._roi_y_max = ControlSlider('ROI y right') # self._blobsize = ControlSlider('Minimum blob size', 100, 100, 2000) self._player = ControlPlayer('Player') self._runbutton = ControlButton('Run') self._start_frame = ControlText('Start Frame') self._stop_frame = ControlText('Stop Frame') self._color_list = ControlCombo('Color channels') self._color_list.add_item('Red Image Channel', 2) self._color_list.add_item('Green Image Channel', 1) self._color_list.add_item('Blue Image Channel', 0) self._clahe = ControlCheckBox('CLAHE ') self._dilate = ControlCheckBox('Morphological Dilation') self._dilate_type = ControlCombo('Dilation Kernel Type') self._dilate_type.add_item('RECTANGLE', cv2.MORPH_RECT) self._dilate_type.add_item('ELLIPSE', cv2.MORPH_ELLIPSE) self._dilate_type.add_item('CROSS', cv2.MORPH_CROSS) self._dilate_size = ControlSlider('Dilation Kernel Size', default=3, min=1, max=10) self._dilate_size.value = 5 self._dilate_size.min = 1 self._dilate_size.max = 10 self._erode = ControlCheckBox('Morphological Erosion') self._erode_type = ControlCombo('Erode Kernel Type') self._erode_type.add_item('RECTANGLE', cv2.MORPH_RECT) self._erode_type.add_item('ELLIPSE', cv2.MORPH_ELLIPSE) self._erode_type.add_item('CROSS', cv2.MORPH_CROSS) self._erode_size = ControlSlider('Erode Kernel Size') self._erode_size.value = 5 self._erode_size.min = 1 self._erode_size.max = 10 self._open = ControlCheckBox('Morphological Opening') self._open_type = ControlCombo('Open Kernel Type') self._open_type.add_item('RECTANGLE', cv2.MORPH_RECT) self._open_type.add_item('ELLIPSE', cv2.MORPH_ELLIPSE) self._open_type.add_item('CROSS', cv2.MORPH_CROSS) self._open_size = ControlSlider('Open Kernel Size') self._open_size.value = 20 self._open_size.min = 1 self._open_size.max = 40 self._close = ControlCheckBox('Morphological Closing') self._close_type = ControlCombo('Close Kernel Type') self._close_type.add_item('RECTANGLE', cv2.MORPH_RECT) self._close_type.add_item('ELLIPSE', cv2.MORPH_ELLIPSE) self._close_type.add_item('CROSS', cv2.MORPH_CROSS) self._close_size = ControlSlider('Close Kernel Size', default=19, min=1, max=40) self._close_size.value = 20 self._close_size.min = 1 self._close_size.max = 40 self._LoG = ControlCheckBox('LoG - Laplacian of Gaussian') self._LoG_size = ControlSlider('LoG Kernel Size') self._LoG_size.value = 20 self._LoG_size.min = 1 self._LoG_size.max = 60 self._progress_bar = ControlProgress('Progress Bar') # Define the function that will be called when a file is selected self._videofile.changed_event = self.__video_file_selection_event # Define the event that will be called when the run button is processed self._runbutton.value = self.__run_event # Define the event called before showing the image in the player self._player.process_frame_event = self.__process_frame self._error_massages = {} # Define the organization of the Form Controls self.formset = [ ('_videofile', '_outputfile'), ('_start_frame', '_stop_frame'), ('_color_list', '_clahe', '_roi_x_min', '_roi_y_min'), ('_threshold_box', '_threshold', '_roi_x_max', '_roi_y_max'), ('_dilate', '_erode', '_open', '_close'), ('_dilate_type', '_erode_type', '_open_type', '_close_type'), ('_dilate_size', '_erode_size', '_open_size', '_close_size'), ('_LoG', '_LoG_size'), ('_runbutton', '_progress_bar'), '_player' ] self.is_roi_set = False
def __init__(self): global conf; conf += 'pythonvideoannotator.resources' # Resources can only be loaded after pyqt is running super(BaseModule, self).__init__('Video annotation editor') self._project = Project(parent=self) Dialog.project = self._project self._player = ControlPlayer("Player") self._time = ControlEventTimeline('Time') self._dock = ControlDockWidget("Timeline", side='bottom', order=1, margin=5) self.formset = ['_player'] self._dock.value = self._time self._player.process_frame_event = self.process_frame_event self._player.click_event = self.on_player_click_event self._time.key_release_event = lambda x: x self._player.key_release_event = lambda x: x self.load_order = [] self.mainmenu.insert(0, {'File': [ {'Open': self.__open_project_event, 'icon': conf.ANNOTATOR_ICON_OPEN}, '-', {'Save': self.__save_project_event , 'icon': conf.ANNOTATOR_ICON_SAVE}, {'Save as': self.__save_project_as_event, 'icon': conf.ANNOTATOR_ICON_SAVE}, '-', {'Exit': QApplication.closeAllWindows, 'icon': conf.ANNOTATOR_ICON_EXIT} ] } ) self.mainmenu.insert(1, {'Modules': []} ) self.mainmenu.insert(2, {'Windows': []} ) track_user_stats() ######################################################################## ###### CHECK NEW VERSIONS RELEASES ##################################### ######################################################################## try: versions = pypi_xmlrpc.package_releases('Python-video-annotator') if versions is not None: new_version = versions[0] if float(new_version) > float(__version__): response = self.question( "<h2>New version <b>[{0}]</b> available</h2>" "<p>Do you wish to update the software?</p>" "<p>The software can be updated later by running the next command in the terminal:</p>" "<i>pip install python-video-annotator --force-reinstall</i>".format(new_version), 'New version [{0}]'.format(new_version) ) if response == 'yes': subprocess.call([sys.executable, "-m", "pip", "install", 'python-video-annotator', '--force-reinstall']) self.message('The software was updated and this session will be closed. Please execute the software again.', 'Restart required') exit() else: print('Enabled to check new versions') except Exception as e: print('Enabled to check new versions:')
class MotionCounter(BaseWidget): def __init__(self, parent=None): BaseWidget.__init__(self, 'Motion counter', parent_win=parent) self.set_margin(5) self.setMinimumHeight(300) self.setMinimumWidth(500) self._player = ControlPlayer('Player') self._datasets = ControlEmptyWidget('Paths', default=DatasetsDialog()) self._backgrounds = ControlEmptyWidget('Backgrounds', default=ObjectsDialog()) self._show_diff = ControlCheckBox('Show diffs boxes') self._threshold = ControlSlider('Threshold', default=5, minimum=1, maximum=255) self._radius = ControlSlider('Radius', default=30, minimum=1, maximum=200) self._apply = ControlButton('Apply', checkable=True) self._compare = ControlCombo('Compare with') self._progress = ControlProgress('Progress') self._formset = [ '_datasets', '=', '_compare', '_backgrounds', ('_threshold', '_radius', '_show_diff'), '_player', '_apply', '_progress' ] self._compare.add_item('Last frame', 1) self._compare.add_item('First frame', 2) self._compare.add_item('Background image', 3) self.load_order = ['_threshold', '_radius', '_show_diff'] self._backgrounds.value.datasets_filter = lambda x: isinstance( x, Image) self._datasets.value.datasets_filter = lambda x: isinstance( x, (Contours, Path)) self._player.process_frame_event = self.__process_frame_event self._datasets.value.video_selection_changed_event = self.__video_selection_changed_event self._compare.changed_event = self.__compare_changed_event self._apply.value = self.__apply_btn_event self._apply.icon = conf.ANNOTATOR_ICON_MOTION self._progress.hide() self._backgrounds.hide() ########################################################################### ### EVENTS ################################################################ ########################################################################### def __compare_changed_event(self): if self._compare.value == 1: self._backgrounds.hide() elif self._compare.value == 2: self._backgrounds.hide() elif self._compare.value == 3: self._backgrounds.show() self._lastframe = None def __video_selection_changed_event(self): video = self._datasets.value.selected_video if video is not None: self._player.value = video.video_capture def __process_frame_event(self, frame): index = self._player.video_index - 1 selected_video = self._datasets.value.selected_video radius = self._radius.value threshold = self._threshold.value show_diff = self._show_diff.value compare_with = self._compare.value if compare_with == 3 and len(self._backgrounds.value.objects): background_img = self._backgrounds.value.objects[0].image background_img = cv2.cvtColor(background_img, cv2.COLOR_BGR2GRAY) else: background_img = None for video, (begin, end), datasets in self._datasets.value.selected_data: if video != selected_video: continue for dataset in datasets: pos = dataset.get_position(index) if pos is None: continue if show_diff: # calculate the cut x, y = pos cutx = int(round(x - radius)) cuty = int(round(y - radius)) cutxx = int(round(x + radius)) cutyy = int(round(y + radius)) if cutx < 0: cutx = 0 if cutxx > frame.shape[1]: cutxx = frame.shape[1] if cuty < 0: cuty = 0 if cutyy > frame.shape[0]: cutyy = frame.shape[0] gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) small = gray[cuty:cutyy, cutx:cutxx].copy() circular_mask = np.zeros((cutyy - cuty, cutxx - cutx), dtype=np.uint8) cv2.circle(circular_mask, (cutyy - cuty, cutxx - cutx), radius, 255, -1) small_masked = cv2.bitwise_and(circular_mask, small) if not hasattr(self, '_lastframe') or type( self._lastframe) is not np.ndarray: if self._compare.value == 1 or self._compare.value == 2: self._lastframe = gray elif self._compare.value == 3: self._lastframe = background_img if type(self._lastframe) is np.ndarray: last_masked = cv2.bitwise_and( circular_mask, self._lastframe[cuty:cutyy, cutx:cutxx]) diff = cv2.absdiff(small_masked, last_masked) cv2.circle(frame, pos, radius, (0, 0, 0), -1) frame[cuty:cutyy, cutx:cutxx] += cv2.merge( (diff, diff, diff)) if self._compare.value == 1: self._lastframe = gray else: cv2.circle(frame, pos, radius, (0, 0, 255), 2) return frame def __apply_btn_event(self): if self._apply.checked: self._datasets.enabled = False self._show_diff.enabled = False self._threshold.enabled = False self._player.enabled = False self._radius.enabled = False self._player.stop() self._apply.label = 'Cancel' total_2_analyse = 0 for video, (begin, end), datasets in self._datasets.value.selected_data: total_2_analyse += end - begin + 1 self._progress.min = 0 self._progress.max = total_2_analyse self._progress.show() radius = self._radius.value threshold = self._threshold.value count = 0 for video, (begin, end), datasets in self._datasets.value.selected_data: begin = int(begin) end = int(end) + 1 capture = cv2.VideoCapture(video.filepath) capture.set(cv2.CAP_PROP_POS_FRAMES, begin) last_image = [None for x in datasets] compare_with = self._compare.value if compare_with == 3: if len(self._backgrounds.value.objects): background_img = self._backgrounds.value.objects[ 0].image background_img = cv2.cvtColor(background_img, cv2.COLOR_BGR2GRAY) else: self.critical('No background selected') break else: background_img = None for index in range(begin, end): res, frame = capture.read() if not res: break if not self._apply.checked: break for dataset_index, dataset in enumerate(datasets): pos = dataset.get_position(index) if pos is None: continue x, y = pos cutx = int(round(x - radius)) cuty = int(round(y - radius)) cutxx = int(round(x + radius)) cutyy = int(round(y + radius)) if cutx < 0: cutx = 0 if cutxx > frame.shape[1]: cutxx = frame.shape[1] if cuty < 0: cuty = 0 if cutyy > frame.shape[0]: cutyy = frame.shape[0] gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) small = gray[cuty:cutyy, cutx:cutxx].copy() circular_mask = np.zeros((cutyy - cuty, cutxx - cutx), dtype=np.uint8) cv2.circle(circular_mask, (cutyy - cuty, cutxx - cutx), radius, 255, -1) small_masked = cv2.bitwise_and(small, small, circular_mask) if type(last_image[dataset_index]) is not np.ndarray: last_image[dataset_index] = small_masked if compare_with == 1 or compare_with == 2: last_image[dataset_index] = gray elif compare_with == 3: last_image[dataset_index] = background_img segment = last_image[dataset_index] last_masked = cv2.bitwise_and( circular_mask, segment[cuty:cutyy, cutx:cutxx]) diff = cv2.absdiff(small_masked, last_masked) diff[diff < threshold] = 0 diff[diff >= threshold] = 1 motion = np.sum(diff) dataset.set_motion(index, motion) if compare_with == 1: last_image[dataset_index] = gray self._progress.value = count count += 1 self._datasets.enabled = True self._show_diff.enabled = True self._threshold.enabled = True self._player.enabled = True self._radius.enabled = True self._apply.label = 'Apply' self._apply.checked = False self._progress.hide()
class QuadView(BaseWidget): def __init__(self, *args, **kwargs): super().__init__('4-Cam') self.set_margin(10) # Definition of the forms fields self._player1 = ControlPlayer('Player1') self._player2 = ControlPlayer('Player2') self._player3 = ControlPlayer('Player3') self._player4 = ControlPlayer('Player4') self._runbutton = ControlButton('Stop') self._screenshot = ControlButton('Screenshot') self._outputfile = ControlDir('Screenshots Ausgabe Ordner') self._cams = ControlCheckBoxList('Kameras') # Define the event that will be called when the run button is processed self._runbutton.value = self.__stopEvent self._screenshot.value = self._saveImages self.__check_all_avaliable_cameras() self.formset = [{ '0-Kameras': [('_runbutton'), ('_player1', '_player2'), ('_player3', '_player4')], '1-Einstellungen': [('_outputfile'), ('_cams')] }] self._player1.value = self.__assign_capture(0) self._player2.value = self.__assign_capture(1) self._player3.value = self.__assign_capture(2) self._player4.value = self.__assign_capture(3) self._outputfile.value = os.getcwd() self.__runEvent() def __assign_capture(self, player_id): checked_cam_ids = self._cams.checked_indexes if checked_cam_ids.__len__() > player_id: return cv2.VideoCapture(checked_cam_ids[player_id]) return cv2.VideoCapture() def __runEvent(self): """ After setting the best parameters run the full algorithm """ self._player1.update_frame() self._player1.play() self._player2.update_frame() self._player2.play() self._player3.update_frame() self._player3.play() self._player4.update_frame() self._player4.play() pass def __stopEvent(self): self._player1.stop() self._player2.stop() self._player3.stop() self._player4.stop() def _saveImages(self): """ Saves the Images of all cams to a file :return: """ currentTime = str(strftime("%Y-%m-%d_%H:%M:%S", gmtime())) cv2.imwrite( os.path.join(self._outputfile.value, currentTime + '_cam_1.png'), self._player1.value['frame']) cv2.imwrite( os.path.join(self._outputfile.value, currentTime + '_cam_2.png'), self._player2.value['frame']) cv2.imwrite( os.path.join(self._outputfile.value, currentTime + '_cam_3.png'), self._player3.value['frame']) cv2.imwrite( os.path.join(self._outputfile.value, currentTime + '_cam_4.png'), self._player4.value['frame']) print("Written screenshots to disk") pass def accessible_device(self, source): cap = cv2.VideoCapture(source) if cap is None or not cap.isOpened(): return False cap.release() return True def __check_all_avaliable_cameras(self): for x in range(0, 10): isCam = self.accessible_device(x) if isCam: self._cams += ('Kamera ' + str(x), True)
def __init__(self): super(BaseStation, self).__init__('Station de base') self.robot = None #Definition of the forms fields self.textArea = ControlTextArea('Log') self.textTimer = ControlText('Timer') self.textState = ControlText('État') self.textVolt = ControlText('Voltage') self.textCourant = ControlText('Courant')#slot courant self.textPos = ControlText('Position') self.textPiece = ControlText('Pièce') self.textPlayer = ControlPlayer('Playground') self.textImage = ControlImage('Field') self.buttonLog = ControlButton('Start') self.buttonReset = ControlButton('Reset') self.formset = ['', '||', 'textArea', '||', (('textState', '||', 'textPiece'), '=', ('textVolt', '||', 'textCourant'), '=', ('textPos', '||', 'textTimer'), '=', ('buttonLog', '||', 'buttonReset'), '=', ('textPlayer', '||')), '||', '', '=', ''] # Define the button action self.buttonLog.value = self.button_log_action self.buttonReset.value = self.button_reset_action # Define communication entre les thread self.thread_com_log = Communicate() self.thread_com_log.speak[str].connect(self.update_log) self.thread_com_state = Communicate() self.thread_com_state.speak[str].connect(self.update_state) self.thread_com_volt = Communicate() self.thread_com_volt.speak[str].connect(self.update_volt) self.thread_com_pos = Communicate() self.thread_com_pos.speak[str].connect(self.update_pos) self.thread_com_piece = Communicate() self.thread_com_piece.speak[str].connect(self.update_piece) self.thread_com_image = Communicate() self.thread_com_image.speak[np.ndarray].connect(self.update_image) self.thread_com_timer = Communicate() self.thread_com_timer.speak[str].connect(self.update_timer) self.thread_com_courant = Communicate() self.thread_com_courant.speak[str].connect(self.update_courant) self.vision = MainController(self) self.web_socket = WebSocket(self.textArea, self) # debut visison/pathfinding self.camera_monde = CameraMonde(self.textPlayer, self) self.camera_monde.thread_start_camera() self.draw_playgroung = DrawPlayground(self.textImage, self.textPos) #self.draw_playgroung.draw_robot(8, 3) self.world = None self.image = None self.path_finding = None self.qr_Code = None
class GeometryManualDesigner(BaseWidget): def __init__(self, title, parent=None): super(GeometryManualDesigner, self).__init__(title, parent_win=parent) self._threshold_win = None self._start_point = None self._end_point = None self._selected_poly = None self._selected_point = None self._video = ControlFile("Video file") self._player = ControlPlayer("Video") self._remove = ControlButton("Remove") self._square = ControlButton("Square", checkable=True) self._circle = ControlButton("Circle", checkable=True) self._threshold = ControlButton("Threshold") self._export = ControlButton("Export") self._import = ControlButton("Import") self._polygons = ControlList('Polygons') self._apply = ControlButton('Apply') self._formset = [ '_video', "_player", ("_square", "_circle", "_threshold", " ", "_remove", " ", "_export", "_import"), "=", "_polygons", '_apply' ] self._video.changedchanged_event = self.videoSelected self._square.value = self.square_toggle self._circle.value = self.circle_toggle self._remove.value = self.remove_clicked self._export.value = self.export_clicked self._import.value = self.import_clicked self._threshold.value = self.threshold_btn_click self._player.drag_event = self.on_player_drag_in_video_window self._player.end_drag_event = self.on_player_end_drag_in_video_window self._player.click_event = self.on_player_click_in_video_window self._player.double_click_event = self.on_player_double_click_in_video_window self._player.process_frame_event = self.process_frame self._player.key_release_event = self.on_player_key_release self._apply.hide() def on_player_key_release(self, event): if event.key() == QtCore.Qt.Key_Delete: if self._selected_poly != None and self._selected_point != None: poly = self._polygons.get_value(1, self._selected_poly) try: points = list(eval(poly)) p = points.pop(self._selected_point) self._polygons.set_value(1, self._selected_poly, str(points)[1:-1]) if not self._player.is_playing: self._player.refresh() except: pass def export_clicked(self): filename = str(QFileDialog.getSaveFileName(self, 'Choose a file', '')) if filename != "": output = open(filename, 'w') for values in self._polygons.value: output.write((';'.join(values) + '\n')) output.close() def import_clicked(self): filename = str(QFileDialog.getOpenFileName(self, 'Choose a file', '')) if filename != "": infile = open(filename, 'r') polygons = [] for line in infile: values = line.split(';') name = values[0] poly = values[1] polygons.append((name, poly)) self._polygons.value += polygons def process_frame(self, frame): rows = self._polygons.value for objIndex, obj in enumerate(rows): points = eval(obj[1]) cv2.polylines(frame, [np.array(points, np.int32)], True, (0, 255, 0), 2, lineType=cv2.LINE_AA) for pointIndex, point in enumerate(points): if self._selected_point == pointIndex and objIndex == self._selected_poly: cv2.circle(frame, point, 4, (0, 0, 255), 2) else: cv2.circle(frame, point, 4, (0, 255, 0), 2) if self._start_point and self._end_point: if self._square.checked: cv2.rectangle(frame, self._start_point, self._end_point, (233, 44, 44), 2) elif self._circle.checked and self._end_point[ 0] > self._start_point[0] and self._end_point[ 1] > self._start_point[1]: width = self._end_point[0] - self._start_point[0] height = self._end_point[1] - self._start_point[1] center = (self._start_point[0] + width / 2, self._start_point[1] + height / 2) cv2.ellipse(frame, (center, (width, height), 0), (233, 44, 44), 2) return frame def selectPoint(self, x, y): rows = self._polygons.value for objIndex, obj in enumerate(rows): try: mouseCoord = (x, y) points = eval(obj[1]) for pointIndex, point in enumerate(points): if pointsDistance(mouseCoord, point) <= 5: self._selected_point = pointIndex self._selected_poly = objIndex return self._selected_point = None self._selected_poly = None except: pass def get_intersection_point_distance(self, test_point, point1, point2): p1 = np.float32(point1) p2 = np.float32(point2) p3 = np.float32(test_point) dist = np.linalg.norm(np.cross(p2 - p1, p1 - p3)) / np.linalg.norm(p2 - p1) return dist def on_player_double_click_in_video_window(self, event, x, y): mouse = (int(x), int(y)) rows = self._polygons.value distances = [] for obj_index, obj in enumerate(rows): try: points = list(eval(obj[1])) n_points = len(points) for point_index, point in enumerate(points): next_point = points[(point_index + 1) % n_points] distance = self.get_intersection_point_distance( mouse, point, next_point) if distance <= 5: vector = next_point[0] - point[0], next_point[ 1] - point[1] center = point[0] + vector[0] / 2, point[ 1] + vector[1] / 2 radius = pointsDistance(center, point) mouse_distance = pointsDistance(center, mouse) if mouse_distance < radius: distances.append( (distance, obj_index, point_index)) except: pass if len(distances) > 0: distances = sorted(distances, key=lambda x: x[0]) obj_index = distances[0][1] point_index = distances[0][2] points = list(eval(rows[obj_index][1])) points.insert(point_index + 1, mouse) self._polygons.set_value(1, obj_index, str(points)[1:-1]) self._selected_poly = obj_index self._selected_point = point_index + 1 if not self._player.is_playing: self._player.refresh() def on_player_click_in_video_window(self, event, x, y): self._selected_poly = None self._selected_point = None if not self._square.checked and not self._circle.checked: self.selectPoint(int(x), int(y)) def on_player_drag_in_video_window(self, startPoint, endPoint): self._start_point = (int(startPoint[0]), int(startPoint[1])) self._end_point = (int(endPoint[0]), int(endPoint[1])) if self._selected_poly != None and self._selected_point != None: poly = self._polygons.get_value(1, self._selected_poly) try: points = list(eval(poly)) points[self._selected_point] = self._end_point self._polygons.set_value(1, self._selected_poly, str(points)[1:-1]) except Exception as e: print(e) if not self._player.is_playing: self._player.refresh() def on_player_end_drag_in_video_window(self, startPoint, endPoint): self._start_point = int(startPoint[0]), int(startPoint[1]) self._end_point = int(endPoint[0]), int(endPoint[1]) points = None if self._square.checked: points = createRectanglePoints(self._start_point, self._end_point) elif self._circle.checked and self._end_point[0] > self._start_point[ 0] and self._end_point[1] > self._start_point[1]: points = createEllipsePoints(self._start_point, self._end_point) if points: self._polygons += [ "Poly_%d" % self._polygons.rows_count, str(points)[1:-1] ] self._start_point = None self._end_point = None self._square.checked = False self._circle.checked = False if not self._player.is_playing: self._player.refresh() def __add_contours_from_threshold_win(self, contours): for contour in contours: if contour.any(): points = [tuple(p[0]) for p in contour.tolist()] self._polygons += [ "Poly_%d" % self._polygons.rows_count, str(points)[1:-1] ] def videoSelected(self): self._player.value = self._video.value def square_toggle(self, checked): if checked: self._circle.checked = False def circle_toggle(self, checked): if checked: self._square.checked = False def threshold_btn_click(self): if self._threshold_win is None: self._threshold_win = GeometryFromThreshold(self) self._threshold_win.add_contours = self.__add_contours_from_threshold_win self._threshold_win.show() if len(self._video.value) > 0: self._threshold_win._filename.value = self._video.value def remove_clicked(self): self._polygons -= -1 #Remove the selected row if not self._player.is_playing: self._player.refresh() @property def geometries(self): polys = [] rows = self._polygons.value for objIndex, obj in enumerate(rows): points = eval(obj[1]) polys.append([obj[0], points]) return polys @geometries.setter def geometries(self, value): self._polygons.value = [] for name, poly in value: points = [tuple(p) for p in poly] self._polygons += [name, str(points)[1:-1]] @property def polygons(self): polys = [] rows = self._polygons.value for objIndex, obj in enumerate(rows): points = eval(obj[1]) polys.append(np.array(points, np.int32)) return np.array(polys) @property def apply_event(self): return self._apply.value @apply_event.setter def apply_event(self, value): self._apply.value = value self._show_apply = value is not None def show(self): super(GeometryManualDesigner, self).show() if hasattr(self, '_show_apply') and self._show_apply: self._apply.show() @property def video_filename(self): return None @video_filename.setter def video_filename(self, value): self._video.hide() self._player.value = value @property def video_capture(self): return self.video_capture.value @video_capture.setter def video_capture(self, value): self._video.hide() self._player.value = value @property def total_n_frames(self): if self._player._value is not None and self._player.value != '': return self._player.max else: return 0
class BaseModule(BaseWidget): """Application form""" def __init__(self): global conf; conf += 'pythonvideoannotator.resources' # Resources can only be loaded after pyqt is running super(BaseModule, self).__init__('Video annotation editor') self._project = Project(parent=self) Dialog.project = self._project self._player = ControlPlayer("Player") self._time = ControlEventTimeline('Time') self._dock = ControlDockWidget("Timeline", side='bottom', order=1, margin=5) self.formset = ['_player'] self._dock.value = self._time self._player.process_frame_event = self.process_frame_event self._player.click_event = self.on_player_click_event self._time.key_release_event = lambda x: x self._player.key_release_event = lambda x: x self.load_order = [] self.mainmenu.insert(0, {'File': [ {'Open': self.__open_project_event, 'icon': conf.ANNOTATOR_ICON_OPEN}, '-', {'Save': self.__save_project_event , 'icon': conf.ANNOTATOR_ICON_SAVE}, {'Save as': self.__save_project_as_event, 'icon': conf.ANNOTATOR_ICON_SAVE}, '-', {'Exit': QApplication.closeAllWindows, 'icon': conf.ANNOTATOR_ICON_EXIT} ] } ) self.mainmenu.insert(1, {'Modules': []} ) self.mainmenu.insert(2, {'Windows': []} ) track_user_stats() ######################################################################## ###### CHECK NEW VERSIONS RELEASES ##################################### ######################################################################## try: versions = pypi_xmlrpc.package_releases('Python-video-annotator') if versions is not None: new_version = versions[0] if float(new_version) > float(__version__): response = self.question( "<h2>New version <b>[{0}]</b> available</h2>" "<p>Do you wish to update the software?</p>" "<p>The software can be updated later by running the next command in the terminal:</p>" "<i>pip install python-video-annotator --force-reinstall</i>".format(new_version), 'New version [{0}]'.format(new_version) ) if response == 'yes': subprocess.call([sys.executable, "-m", "pip", "install", 'python-video-annotator', '--force-reinstall']) self.message('The software was updated and this session will be closed. Please execute the software again.', 'Restart required') exit() else: print('Enabled to check new versions') except Exception as e: print('Enabled to check new versions:') ###################################################################################### #### FUNCTIONS ####################################################################### ###################################################################################### def init_form(self): super(BaseModule, self).init_form() if conf.CHART_FILE_PATH: self._time.import_chart(*conf.CHART_FILE_PATH) if conf.PROJECT_PATH: self.load_project(conf.PROJECT_PATH) ###################################################################################### #### IO FUNCTIONS #################################################################### ###################################################################################### def save(self, data, project_path=None): self._project.save(data, project_path) return data def load(self, data, project_path=None): try: self._project.load(data, project_path) except FileNotFoundError as e: QMessageBox.critical(self, "Error", str(e)) def save_project(self, project_path=None): try: if project_path is None: project_path = QFileDialog.getExistingDirectory(self, "Select the project directory") if project_path is not None and str(project_path)!='': project_path = str(project_path) self.save({}, project_path) except Exception as e: QMessageBox.critical(self, "Error", str(e)) def load_project(self, project_path=None): if project_path is None: project_path = QFileDialog.getExistingDirectory(self, "Select the project directory") if project_path is not None and str(project_path)!='': self.load({}, str(project_path) ) ###################################################################################### #### EVENTS ########################################################################## ###################################################################################### def on_player_click_event(self, event, x, y): """ Code to select a blob with the mouse """ super(VideoAnnotationEditor, self).on_player_click_event(event, x, y) self._player.refresh() def process_frame_event(self, frame): """ Function called before render each frame """ return frame def add_dataset_event(self, dataset): pass def removed_dataset_event(self, dataset): pass def removed_object_event(self, obj): pass def __open_project_event(self): self.load_project() def __save_project_event(self): print('Project saved') self.save_project(self._project.directory) def __save_project_as_event(self): self.save_project() def keyReleaseEvent(self, event): ###################################################################################### #### SPECIFIC SHORTCUTS############################################################### ###################################################################################### #Go to the next event and then click the mark the point button if event.key() == QtCore.Qt.Key_I: if self.timeline.timeline_widget.selected is not None and self.timeline.timeline_widget.selected != self.timeline.timeline_widget.pointer: self.move_to_next_event() self.mark_point() ###################################################################################### #### DOCK SHORTCUTS ################################################################## ###################################################################################### #Select the path of the next object if event.key() == QtCore.Qt.Key_U: self.select_next_path() #"Click" the Mark Point button in the current Path elif event.key() == QtCore.Qt.Key_O: self.mark_point() ###################################################################################### #### TIMELINE SHORTCUTS ############################################################## ###################################################################################### if self.timeline.timeline_widget.selected is not None: modifier = int(event.modifiers()) if modifier == QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_Left: self.move_event_or_pointer_left(event) if modifier == QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_Right: self.move_event_or_pointer_right(event) if self.timeline.timeline_widget.selected != self.timeline.timeline_widget.pointer: # Delete the selected event if event.key() == QtCore.Qt.Key_Delete: self.timeline.timeline_widget.remove_selected_event() # Lock or unlock an event if event.key() == QtCore.Qt.Key_L: self.timeline.timeline_widget.toggle_selected_event_lock() if event.key() == QtCore.Qt.Key_E: self.move_to_next_event() if event.key() == QtCore.Qt.Key_Q: self.move_to_previous_event() if modifier == QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_Up: self.move_event_up() if modifier == QtCore.Qt.ControlModifier and event.key() == QtCore.Qt.Key_Down: self.move_event_down() if modifier == int( QtCore.Qt.ShiftModifier | QtCore.Qt.ControlModifier) and event.key() == QtCore.Qt.Key_Left: self.move_event_end_left() if modifier == int( QtCore.Qt.ShiftModifier | QtCore.Qt.ControlModifier) and event.key() == QtCore.Qt.Key_Right: self.move_event_end_right() if modifier == QtCore.Qt.ShiftModifier and event.key() == QtCore.Qt.Key_Left: self.move_event_begin_left() if modifier == QtCore.Qt.ShiftModifier and event.key() == QtCore.Qt.Key_Right: self.move_event_begin_right() else: if event.key() == QtCore.Qt.Key_S: self.create_event_at_current_frame() # walk backwards 1 step elif event.key() == QtCore.Qt.Key_A: self.timeline.timeline_widget.position = self.timeline.timeline_widget.position - 1 # forward 1 step elif event.key() == QtCore.Qt.Key_D: self.timeline.timeline_widget.position = self.timeline.timeline_widget.position + 1 elif event.key() == QtCore.Qt.Key_E: self.move_to_first_event() elif event.key() == QtCore.Qt.Key_Q: self.move_to_last_event() ###################################################################################### #### PLAYER SHORTCUTS ################################################################ ###################################################################################### # Control video playback using the space bar to Play/Pause if event.key() == QtCore.Qt.Key_Space: if self.player.video_widget.control.is_playing: self.player.video_widget.control.stop() else: self.player.video_widget.control.play() # Jumps 1 frame backwards elif event.key() == QtCore.Qt.Key_A: self.player.video_widget.control.video_index -= 2 self.player.video_widget.control.call_next_frame() # Jumps 1 frame forward elif event.key() == QtCore.Qt.Key_D: self.player.video_widget.control.call_next_frame() # Jumps 20 seconds backwards elif event.key() == QtCore.Qt.Key_Z: self.player.video_widget.control.jump_backward() self.player.video_widget.control.call_next_frame() # Jumps 20 seconds forward elif event.key() == QtCore.Qt.Key_C: self.player.video_widget.control.jump_forward() self.player.video_widget.control.call_next_frame() elif event.key() == QtCore.Qt.Key_M: self._move_img = False elif event.key() == QtCore.Qt.Key_1: self.player.video_widget.control.next_frame_step = 1 self.player.video_widget.show_tmp_msg('Speed: 1x') elif event.key() == QtCore.Qt.Key_2: self.player.video_widget.control.next_frame_step = 2 self.player.video_widget.show_tmp_msg('Speed: 2x') elif event.key() == QtCore.Qt.Key_3: self.player.video_widget.control.next_frame_step = 3 self.player.video_widget.show_tmp_msg('Speed: 3x') elif event.key() == QtCore.Qt.Key_4: self.player.video_widget.control.next_frame_step = 4 self.player.video_widget.show_tmp_msg('Speed: 4x') elif event.key() == QtCore.Qt.Key_5: self.player.video_widget.control.next_frame_step = 5 self.player.video_widget.show_tmp_msg('Speed: 5x') elif event.key() == QtCore.Qt.Key_6: self.player.video_widget.control.next_frame_step = 6 self.player.video_widget.show_tmp_msg('Speed: 6x') elif event.key() == QtCore.Qt.Key_7: self.player.video_widget.control.next_frame_step = 7 self.player.video_widget.show_tmp_msg('Speed: 7x') elif event.key() == QtCore.Qt.Key_8: self.player.video_widget.control.next_frame_step = 8 self.player.video_widget.show_tmp_msg('Speed: 8x') elif event.key() == QtCore.Qt.Key_9: self.player.video_widget.control.next_frame_step = 9 self.player.video_widget.show_tmp_msg('Speed: 9x') ###################################################################################### #### EVENT FUNCTIONS ################################################################# ###################################################################################### def select_next_path(self): selected = self.project.tree.selected_item if selected is not None: #If it's a video, try to select its first object and the object's first child if isinstance(selected.win, Video): if selected.childCount() > 0: child_object = selected.child(0) if child_object.childCount() > 0: self.project.tree.selected_item = child_object.child(0) #If it's an object, try to select it's first child elif isinstance(selected.win, Object2D): if selected.childCount() > 0: self.project.tree.selected_item = selected.child(0) #If it's a path try to select the first child of the next object of their parent video elif isinstance(selected.win, Path): parent_object = selected.parent() parent_video = parent_object.parent() parent_object_index = parent_video.indexOfChild(parent_object) if parent_object_index < parent_video.childCount() -1 : next_object = parent_video.child(parent_video.indexOfChild(parent_object)+1) if next_object.childCount() > 0: self.project.tree.selected_item = next_object.child(0) #If it's the last object of the video, go back to the path of the first one else: next_object = parent_video.child(0) if next_object.childCount() > 0: self.project.tree.selected_item = next_object.child(0) def mark_point(self): selected = self.project.tree.selected_item if selected is not None and isinstance(selected.win, Path): path = selected.win path.mark_point_button.click() def move_to_next_event(self): index = self.timeline.timeline_widget.selected_row.events.index(self.timeline.timeline_widget.selected) if index < len(self.timeline.timeline_widget.selected_row.events)-1: self.timeline.timeline_widget.selected = self.timeline.timeline_widget.selected_row.events[index+1] self.timeline.timeline_widget.position = self.timeline.timeline_widget.selected.begin def move_to_previous_event(self): index = self.timeline.timeline_widget.selected_row.events.index(self.timeline.timeline_widget.selected) if index > 0: self.timeline.timeline_widget.selected = self.timeline.timeline_widget.selected_row.events[index - 1] self.timeline.timeline_widget.position = self.timeline.timeline_widget.selected.begin def move_to_first_event(self): if self.timeline.timeline_widget.selected_row is not None and len(self.timeline.timeline_widget.selected_row)>0: self.timeline.timeline_widget.selected = self.timeline.timeline_widget.selected_row.events[0] self.timeline.timeline_widget.position = self.timeline.timeline_widget.selected.begin def move_to_last_event(self): if self.timeline.timeline_widget.selected_row is not None and len(self.timeline.timeline_widget.selected_row)>0: self.timeline.timeline_widget.selected = self.timeline.timeline_widget.selected_row.events[len(self.timeline.timeline_widget.selected_row)-1] self.timeline.timeline_widget.position = self.timeline.timeline_widget.selected.begin def move_event_or_pointer_left(self, event): modifier = int(event.modifiers()) self.timeline.timeline_widget.selected.move(-1, 0) event.ignore() self.timeline.timeline_widget.repaint() def move_event_or_pointer_right(self, event): modifier = int(event.modifiers()) self.timeline.timeline_widget.selected.move(1, 0) event.ignore() self.timeline.timeline_widget.repaint() def move_event_up(self): self.timeline.timeline_widget.selected.move(0, self.timeline.timeline_widget.selected.top_coordinate - self.timeline.timeline_widget.TRACK_HEIGHT) self.timeline.timeline_widget.repaint() def move_event_down(self): self.timeline.timeline_widget.selected.move(0, self.timeline.timeline_widget.selected.top_coordinate + self.timeline.timeline_widget.TRACK_HEIGHT) self.timeline.timeline_widget.repaint() def move_event_end_left(self): self.timeline.timeline_widget.selected.move_end(-1) self.timeline.timeline_widget.repaint() def move_event_end_right(self): self.timeline.timeline_widget.selected.move_end(1) self.timeline.timeline_widget.repaint() def move_event_begin_left(self): self.timeline.timeline_widget.selected.move_begin(-1) self.timeline.timeline_widget.repaint() def move_event_begin_right(self): self.timeline.timeline_widget.selected.move_begin(1) self.timeline.timeline_widget.repaint() def create_event_at_current_frame(self): if not self.timeline.timeline_widget.creating_event: # Start self.timeline.timeline_widget.creating_event_start = self.timeline.timeline_widget.pointer.frame self.timeline.timeline_widget.creating_event = True # TODO Add some indicator that an event is being recorded, like # using the track selector circle to become red else: # End, must be followed right after Start key and have no # effect otherwise self.timeline.timeline_widget.creating_event_end = self.timeline.timeline_widget.pointer.frame start = self.timeline.timeline_widget.creating_event_start end = self.timeline.timeline_widget.creating_event_end comment = "" if end > start: track = self.timeline.timeline_widget.selected_row if track is None and len(self.timeline.timeline_widget.tracks)>0: track = self.timeline.timeline_widget.tracks[0] if track is None: track = self.timeline.timeline_widget.add_track() self.timeline.timeline_widget.add_event(start, end, comment, track=track ) self.timeline.timeline_widget.repaint() self.timeline.timeline_widget.creating_event = False else: self.timeline.timeline_widget.creating_event = False ###################################################################################### #### PROPERTIES ###################################################################### ###################################################################################### @property def timeline(self): return self._time @property def player(self): return self._player @property def video(self): return self._player.value @video.setter def video(self, value): self._player.value = value self._player.enabled = value is not None if value: self._time.max = self._player.max @property def project(self): return self._project
class BatchCount(BaseWidget): def read_classes(self, classes_path): with open(classes_path) as f: class_names = f.readlines() class_names = [c.strip() for c in class_names] return class_names def __init__(self): BaseWidget.__init__(self, 'Batch Object Detection') self.batchFolder = "" self.batchFile = "" self._dir = ControlFile() self.Canvas = ControlPlayer('Canvas') self._label1 = ControlLabel("") self._start = ControlButton("Count") self._clr = ControlButton("Clear count") self._Progress = ControlProgress(label="0/0") self._Progress.min = 0 self._clr.value = self.clr_mongo self.Canvas.value = "./batchDetect/test.jpg" self._dir.changed_event = self.folderpath_event self._start.value = self._startCount def clr_mongo(self): mongo.createDatabase() self.success(msg="All record is cleared") def _startCount(self): if self.question( title="Begin Counting Object", msg= "It would take Lot of time And replace the image with output, Are you Sure?", buttons=["No", "Yes"]) == "yes": file = [] for filename in glob.glob(self.batchFolder + "/*.*"): file.append(filename) files_number = len(file) self._Progress.max = files_number self._label1.value = "" classDict = {} i = 1 classtype = self.read_classes("./model_data/coco_classes.txt") for t in file: try: output, out_boxes, out_classes, path = YOLO.predict( K.get_session(), t, specificPath=True) except: self.alert(self.parent, msg="File shape error") return self._label1.value = "{0} out of {1} files".format( i, files_number) i = i + 1 self._Progress.value = i try: item = [] for j in out_classes: item.append(classtype[j]) for c in item: classDict[c] = classDict.get(c, 0) + 1 except: self.alert(self, msg="error") print(classDict) self._refresh_canvas(file=t) #add data to to mongo collec = mongo.conDB() for _type in classDict: for j in range(classDict.get(_type, 0)): mongo.increment(collec, _type) try: self._refresh_canvas(file=file[0]) plt = mongo.result(collec) self.success(msg="Succes") plt.show() except: pass else: return def folderpath_event(self): print(os.path.dirname(self._dir.value)) self.batchFile = self._dir.value self.batchFolder = os.path.dirname(self.batchFile) if self.batchFolder != "": self._label1.value = "*Every file in " + self.batchFolder + " Will be Count " self._refresh_canvas(file=self._dir.value) def _refresh_canvas(self, file="./batchDetect/test.jpg"): try: self.Canvas.value = file self.Canvas.videoPlay_clicked() except: pass
class BaseModule(BaseWidget): """Application form""" def __init__(self): global conf conf += 'pythonvideoannotator.resources' # Resources can only be loaded after pyqt is running super(BaseModule, self).__init__('Video annotation editor') self._project = Project(parent=self) Dialog.project = self._project self._player = ControlPlayer("Player") self._time = ControlEventTimeline('Time') self._dock = ControlDockWidget("Timeline", side='bottom', order=1, margin=5) self.formset = ['_player'] self._dock.value = self._time self._player.process_frame_event = self.process_frame_event self._player.click_event = self.on_player_click_event self._time.key_release_event = self.__timeline_key_release_event self.load_order = [] self.mainmenu.insert( 0, { 'File': [{ 'Open': self.__open_project_event, 'icon': conf.ANNOTATOR_ICON_OPEN }, '-', { 'Save': self.__save_project_event, 'icon': conf.ANNOTATOR_ICON_SAVE }, { 'Save as': self.__save_project_as_event, 'icon': conf.ANNOTATOR_ICON_SAVE }, '-', { 'Exit': QApplication.closeAllWindows, 'icon': conf.ANNOTATOR_ICON_EXIT }] }) self.mainmenu.insert(1, {'Modules': []}) self.mainmenu.insert(2, {'Windows': []}) track_user_stats() ######################################################################## ###### CHECK NEW VERSIONS RELEASES ##################################### ######################################################################## try: versions = pypi_xmlrpc.package_releases('Python-video-annotator') if versions is not None: new_version = versions[0] new_version_numbers = [int(x) for x in new_version.split('.')] version_numbers = [int(x) for x in __version__.split('.')] for new_n, n in zip(new_version_numbers, version_numbers): if new_n > n: response = self.question( "<h2>New version <b>[{0}]</b> available</h2>" "<p>Do you wish to update the software?</p>" "<p>The software can be updated later by running the next command in the terminal:</p>" "<i>pip install python-video-annotator --force-reinstall</i>" .format(new_version), 'New version [{0}]'.format(new_version)) if response == 'yes': subprocess.call([ sys.executable, "-m", "pip", "install", 'python-video-annotator', '--force-reinstall' ]) self.message( 'The software was updated and this session will be closed. Please execute the software again.', 'Restart required') exit() break else: print('Enabled to check new versions') except Exception as e: print('Enabled to check new versions:') ###################################################################################### #### FUNCTIONS ####################################################################### ###################################################################################### def init_form(self): super(BaseModule, self).init_form() if conf.CHART_FILE_PATH: self._time.import_chart(*conf.CHART_FILE_PATH) if conf.PROJECT_PATH: self.load_project(conf.PROJECT_PATH) ###################################################################################### #### IO FUNCTIONS #################################################################### ###################################################################################### def save(self, data, project_path=None): self._project.save(data, project_path) return data def load(self, data, project_path=None): try: self._project.load(data, project_path) except FileNotFoundError as e: QMessageBox.critical(self, "Error", str(e)) def save_project(self, project_path=None): try: if project_path is None: project_path = QFileDialog.getExistingDirectory( self, "Select the project directory") if project_path is not None and str(project_path) != '': project_path = str(project_path) self.save({}, project_path) except Exception as e: QMessageBox.critical(self, "Error", str(e)) def load_project(self, project_path=None): if project_path is None: project_path = QFileDialog.getExistingDirectory( self, "Select the project directory") if project_path is not None and str(project_path) != '': self.load({}, str(project_path)) ###################################################################################### #### EVENTS ########################################################################## ###################################################################################### def on_player_click_event(self, event, x, y): """ Code to select a blob with the mouse """ super(VideoAnnotationEditor, self).on_player_click_event(event, x, y) self._player.refresh() def process_frame_event(self, frame): """ Function called before render each frame """ return frame def add_dataset_event(self, dataset): pass def removed_dataset_event(self, dataset): pass def removed_object_event(self, obj): pass def __open_project_event(self): self.load_project() def __save_project_event(self): print('Project saved') self.save_project(self._project.directory) def __save_project_as_event(self): self.save_project() def __timeline_key_release_event(self, event): """ Control video playback using the space bar to Play/Pause """ if event.key() == QtCore.Qt.Key_Space: self._player.stop( ) if self._player.is_playing else _player._video.play() ###################################################################################### #### PROPERTIES ###################################################################### ###################################################################################### @property def timeline(self): return self._time @property def player(self): return self._player @property def video(self): return self._player.value @video.setter def video(self, value): self._player.value = value self._player.enabled = value is not None if value: self._time.max = self._player.max @property def project(self): return self._project
class Base(BaseWidget): """Application form""" def __init__(self): global conf conf += 'pythonvideoannotator.resources' # Resources can only be loaded after pyqt is running super().__init__('Video annotation editor') self._project = Project(parent=self) Dialog.project = self._project self._player = ControlPlayer("Player") self._time = ControlEventTimeline('Time') self._dock = ControlDockWidget("Timeline", side='bottom', order=1, margin=5) self._progress = ControlProgress('Progress', visible=False) # define the application toolbar self.toolbar = [ ControlButton('Open', icon=conf.ANNOTATOR_ICON_OPEN, default=self.__open_project_event), ControlButton('Save', icon=conf.ANNOTATOR_ICON_SAVE, default=self.__save_project_event) ] self.formset = ['_player', '_progress'] self._dock.value = self._time self._player.process_frame_event = self.process_frame_event self._player.click_event = self.on_player_click_event self._player.double_click_event = self.on_player_double_click_event self._player.drag_event = self.on_player_drag_event self._player.end_drag_event = self.on_player_end_drag_event # ignore these controls key release event self._time.key_release_event = lambda x: x self._player.key_release_event = lambda x: x self.load_order = [] self.mainmenu.insert( 0, { 'File': [{ 'Open': self.__open_project_event, 'icon': conf.ANNOTATOR_ICON_OPEN }, '-', { 'Save': self.__save_project_event, 'icon': conf.ANNOTATOR_ICON_SAVE }, { 'Save as': self.__save_project_as_event, 'icon': conf.ANNOTATOR_ICON_SAVE }, '-', { 'Exit': QApplication.closeAllWindows, 'icon': conf.ANNOTATOR_ICON_EXIT }] }) self.mainmenu.insert(1, {'Modules': []}) self.mainmenu.insert(2, {'Windows': []}) track_user_stats() ######################################################################## ###### CHECK NEW VERSIONS RELEASES ##################################### ######################################################################## try: versions = pypi_xmlrpc.package_releases('Python-video-annotator') if versions is not None: new_version = versions[0] if float(new_version) > float(__version__): response = self.question( "<h2>New version <b>[{0}]</b> available</h2>" "<p>Do you wish to update the software?</p>" "<p>The software can be updated later by running the next command in the terminal:</p>" "<i>pip install python-video-annotator --force-reinstall</i>" .format(new_version), 'New version [{0}]'.format(new_version)) if response == 'yes': subprocess.call([ sys.executable, "-m", "pip", "install", 'python-video-annotator', '--force-reinstall' ]) self.message( 'The software was updated and this session will be closed. Please execute the software again.', 'Restart required') exit() else: print('Unable to check new versions') except Exception as e: print('Unable to check new versions:') ###################################################################################### #### FUNCTIONS ####################################################################### ###################################################################################### def init_form(self): super().init_form() if conf.CHART_FILE_PATH: self._time.import_chart(*conf.CHART_FILE_PATH) if conf.VIDEOANNOTATOR_PROJECTPATH: self.load_project(conf.VIDEOANNOTATOR_PROJECTPATH) if len(sys.argv) > 1: QTimer.singleShot(1000, self.__load_project_from_argv) ###################################################################################### #### EVENTS ########################################################################## ###################################################################################### def on_player_drag_event(self, p1, p2): if self._project: self._project.player_on_drag(p1, p2) self._player.refresh() def on_player_end_drag_event(self, p1, p2): if self._project: self._project.player_on_end_drag(p1, p2) self._player.refresh() def on_player_click_event(self, event, x, y): """ Code to select a blob with the mouse """ if self._project: self._project.player_on_click(event, x, y) self._player.refresh() def on_player_double_click_event(self, event, x, y): """ Code to select a blob with the mouse """ if self._project: self._project.player_on_double_click(event, x, y) self._player.refresh() def process_frame_event(self, frame): """ Function called before render each frame """ return frame def add_dataset_event(self, dataset): pass def removed_dataset_event(self, dataset): pass def removed_object_event(self, obj): pass def __open_project_event(self): self.load_project() def __save_project_event(self): self.save_project(self._project.directory) def __save_project_as_event(self): self.save_project() def __load_project_from_argv(self): self.load_project(sys.argv[-1]) ###################################################################################### #### EVENT FUNCTIONS ################################################################# ###################################################################################### def select_next_path(self): selected = self.project.tree.selected_item if selected is not None: # If it's a video, try to select its first object and the object's first child if isinstance(selected.win, Video): if selected.childCount() > 0: child_object = selected.child(0) if child_object.childCount() > 0: self.project.tree.selected_item = child_object.child(0) # If it's an object, try to select it's first child elif isinstance(selected.win, Object2D): if selected.childCount() > 0: self.project.tree.selected_item = selected.child(0) # If it's a path try to select the first child of the next object of their parent video elif isinstance(selected.win, Path): parent_object = selected.parent() parent_video = parent_object.parent() parent_object_index = parent_video.indexOfChild(parent_object) if parent_object_index < parent_video.childCount() - 1: next_object = parent_video.child( parent_video.indexOfChild(parent_object) + 1) if next_object.childCount() > 0: self.project.tree.selected_item = next_object.child(0) # If it's the last object of the video, go back to the path of the first one else: next_object = parent_video.child(0) if next_object.childCount() > 0: self.project.tree.selected_item = next_object.child(0) ###################################################################################### ###################################################################################### #### PROPERTIES ###################################################################### ###################################################################################### @property def progress_bar(self): return self._progress @property def timeline(self): return self._time @property def player(self): return self._player @property def video(self): return self._player.value @video.setter def video(self, value): self._player.value = value self._player.enabled = value is not None if value: self._time.max = self._player.max @property def project(self): return self._project
class Pixie(BaseWidget): def __init__(self, *args, **kwargs): super().__init__('Pixie') tempath = "" #mainMenu self.mainmenu = [{ 'File': [{ 'Open': self.__openEvent }, '-', { 'Save': self.__saveEvent }] }] #definition toolsBox = ToolsBox() toolsBox.parent = self self._dockleft = ControlDockWidget() self._dockleft.value = toolsBox self._imglabel = ControlLabel() self._ControlImage = ControlPlayer('canvas') self._ToolsBox__updateImage("") self._detail = ControlLabel('Detail') def __openEvent(self): self.__image_file_selection_event() def __saveEvent(self): if self.path != "": try: copyfile(self.tempath + "-current.jpg", self.path) self.success(msg="Save to " + self.path + " Completed") except: pass pass def __image_file_selection_event(self): open = ControlFile('image') open.click() fname = open.value.split("/") _filename = fname[len(fname) - 1] ## check blank path if open.value == "": return ## is image try: img = cv2.imread(open.value) height, width, alp = img.shape except: self.alert(msg="File is not a image") #check for file type self.tempath = "" self.path = open.value self.title = "Open file " + path self._imglabel.value = _filename self.tempath = TEMP + _filename copyfile(self.path, self.tempath) self._ToolsBox__updateImage(self.tempath) def _ToolsBox__updateImage(self, path): try: self._ControlImage.value = path self._ControlImage.videoPlay_clicked() except: pass ## case no vid load def _ToolsBox__updatedetail(self, txt): self._detail.value = str(txt)
def __init__(self): global conf conf += 'pythonvideoannotator.resources' # Resources can only be loaded after pyqt is running super().__init__('Video annotation editor') self._project = Project(parent=self) Dialog.project = self._project self._player = ControlPlayer("Player") self._time = ControlEventTimeline('Time') self._dock = ControlDockWidget("Timeline", side='bottom', order=1, margin=5) self._progress = ControlProgress('Progress', visible=False) # define the application toolbar self.toolbar = [ ControlButton('Open', icon=conf.ANNOTATOR_ICON_OPEN, default=self.__open_project_event), ControlButton('Save', icon=conf.ANNOTATOR_ICON_SAVE, default=self.__save_project_event) ] self.formset = ['_player', '_progress'] self._dock.value = self._time self._player.process_frame_event = self.process_frame_event self._player.click_event = self.on_player_click_event self._player.double_click_event = self.on_player_double_click_event self._player.drag_event = self.on_player_drag_event self._player.end_drag_event = self.on_player_end_drag_event # ignore these controls key release event self._time.key_release_event = lambda x: x self._player.key_release_event = lambda x: x self.load_order = [] self.mainmenu.insert( 0, { 'File': [{ 'Open': self.__open_project_event, 'icon': conf.ANNOTATOR_ICON_OPEN }, '-', { 'Save': self.__save_project_event, 'icon': conf.ANNOTATOR_ICON_SAVE }, { 'Save as': self.__save_project_as_event, 'icon': conf.ANNOTATOR_ICON_SAVE }, '-', { 'Exit': QApplication.closeAllWindows, 'icon': conf.ANNOTATOR_ICON_EXIT }] }) self.mainmenu.insert(1, {'Modules': []}) self.mainmenu.insert(2, {'Windows': []}) track_user_stats() ######################################################################## ###### CHECK NEW VERSIONS RELEASES ##################################### ######################################################################## try: versions = pypi_xmlrpc.package_releases('Python-video-annotator') if versions is not None: new_version = versions[0] if float(new_version) > float(__version__): response = self.question( "<h2>New version <b>[{0}]</b> available</h2>" "<p>Do you wish to update the software?</p>" "<p>The software can be updated later by running the next command in the terminal:</p>" "<i>pip install python-video-annotator --force-reinstall</i>" .format(new_version), 'New version [{0}]'.format(new_version)) if response == 'yes': subprocess.call([ sys.executable, "-m", "pip", "install", 'python-video-annotator', '--force-reinstall' ]) self.message( 'The software was updated and this session will be closed. Please execute the software again.', 'Restart required') exit() else: print('Unable to check new versions') except Exception as e: print('Unable to check new versions:')
class BaseModule(BaseWidget): """Application form""" def __init__(self): global conf conf += 'pythonvideoannotator.resources' # Resources can only be loaded after pyqt is running super(BaseModule, self).__init__('Video annotation editor') self._project = Project(parent=self) Dialog.project = self._project self._player = ControlPlayer("Player") self._time = ControlEventTimeline('Time') self._dock = ControlDockWidget("Timeline", side='bottom', order=1, margin=5) self.formset = ['_player'] self._dock.value = self._time self._player.process_frame_event = self.process_frame_event self._player.click_event = self.on_player_click_event self._time.key_release_event = self.__timeline_key_release_event self.load_order = [] self.mainmenu.insert( 0, { 'File': [{ 'Open': self.__open_project_event, 'icon': conf.ANNOTATOR_ICON_OPEN }, '-', { 'Save': self.__save_project_event, 'icon': conf.ANNOTATOR_ICON_SAVE }, { 'Save as': self.__save_project_as_event, 'icon': conf.ANNOTATOR_ICON_SAVE }, '-', { 'Exit': QApplication.closeAllWindows, 'icon': conf.ANNOTATOR_ICON_EXIT }] }) self.mainmenu.insert(1, {'Modules': []}) self.mainmenu.insert(2, {'Windows': []}) ###################################################################################### #### FUNCTIONS ####################################################################### ###################################################################################### def init_form(self): super(BaseModule, self).init_form() if conf.CHART_FILE_PATH: self._time.import_chart(*conf.CHART_FILE_PATH) if conf.PROJECT_PATH: self.load_project(conf.PROJECT_PATH) ###################################################################################### #### IO FUNCTIONS #################################################################### ###################################################################################### def save(self, data, project_path=None): self._project.save(data, project_path) return data def load(self, data, project_path=None): self._project.load(data, project_path) def save_project(self, project_path=None): try: if project_path is None: project_path = QFileDialog.getExistingDirectory( self, "Select the project directory") if project_path is not None and str(project_path) != '': project_path = str(project_path) self.save({}, project_path) except Exception as e: QMessageBox.critical(self, "Error", str(e)) def load_project(self, project_path=None): if project_path is None: project_path = QFileDialog.getExistingDirectory( self, "Select the project directory") if project_path is not None and str(project_path) != '': self.load({}, str(project_path)) ###################################################################################### #### EVENTS ########################################################################## ###################################################################################### def on_player_click_event(self, event, x, y): """ Code to select a blob with the mouse """ super(VideoAnnotationEditor, self).on_player_click_event(event, x, y) self._player.refresh() def process_frame_event(self, frame): """ Function called before render each frame """ return frame def __open_project_event(self): self.load_project() def __save_project_event(self): self.save_project(self._project.directory) def __save_project_as_event(self): self.save_project() def __timeline_key_release_event(self, event): """ Control video playback using the space bar to Play/Pause """ if event.key() == QtCore.Qt.Key_Space: self._player.stop( ) if self._player.is_playing else _player._video.play() ###################################################################################### #### PROPERTIES ###################################################################### ###################################################################################### @property def timeline(self): return self._time @property def player(self): return self._player @property def video(self): return self._player.value @video.setter def video(self, value): self._player.value = value self._player.enabled = value is not None if value: self._time.max = self._player.max @property def project(self): return self._project
def __init__(self): global conf conf += 'pythonvideoannotator.resources' # Resources can only be loaded after pyqt is running super(BaseModule, self).__init__('Video annotation editor') self._project = Project(parent=self) Dialog.project = self._project self._player = ControlPlayer("Player") self._time = ControlEventTimeline('Time') self._dock = ControlDockWidget("Timeline", side='bottom', order=1, margin=5) self.formset = ['_player'] self._dock.value = self._time self._player.process_frame_event = self.process_frame_event self._player.click_event = self.on_player_click_event self._time.key_release_event = self.__timeline_key_release_event self.load_order = [] self.mainmenu.insert( 0, { 'File': [{ 'Open': self.__open_project_event, 'icon': conf.ANNOTATOR_ICON_OPEN }, '-', { 'Save': self.__save_project_event, 'icon': conf.ANNOTATOR_ICON_SAVE }, { 'Save as': self.__save_project_as_event, 'icon': conf.ANNOTATOR_ICON_SAVE }, '-', { 'Exit': QApplication.closeAllWindows, 'icon': conf.ANNOTATOR_ICON_EXIT }] }) self.mainmenu.insert(1, {'Modules': []}) self.mainmenu.insert(2, {'Windows': []}) track_user_stats() ######################################################################## ###### CHECK NEW VERSIONS RELEASES ##################################### ######################################################################## try: versions = pypi_xmlrpc.package_releases('Python-video-annotator') if versions is not None: new_version = versions[0] new_version_numbers = [int(x) for x in new_version.split('.')] version_numbers = [int(x) for x in __version__.split('.')] for new_n, n in zip(new_version_numbers, version_numbers): if new_n > n: response = self.question( "<h2>New version <b>[{0}]</b> available</h2>" "<p>Do you wish to update the software?</p>" "<p>The software can be updated later by running the next command in the terminal:</p>" "<i>pip install python-video-annotator --force-reinstall</i>" .format(new_version), 'New version [{0}]'.format(new_version)) if response == 'yes': subprocess.call([ sys.executable, "-m", "pip", "install", 'python-video-annotator', '--force-reinstall' ]) self.message( 'The software was updated and this session will be closed. Please execute the software again.', 'Restart required') exit() break else: print('Enabled to check new versions') except Exception as e: print('Enabled to check new versions:')