class MyDialog(QtWidgets.QMainWindow): def __init__(self, app): super(MyDialog, self).__init__() #MainWindow.setUnifiedTitleAndToolBarOnMac(True) self.app = app self.tr = self.app.tr self.ui = Ui_MainWindow() self.translator = QtCore.QTranslator(app) self.app.installTranslator(self.translator) # set system locale self.ui.setupUi(self) self.set_up_ui_actions() def get_method(self): if self.ui.process_hog_radioButton.isChecked(): return 'hog' elif self.ui.process_cnn_radioButton.isChecked(): return 'cnn' else: raise NotImplementedError def extract_select_input(self, path): # path is a typle of (filename, filter) if path[0]: self.ui.extract_input_text.setText(path[0]) def extract_select_output(self, path): if path: self.ui.extract_output_text.setText(path) process_select_input(self, path) def process_select_input(self, path): if path: self.ui.process_input_text.setText(path) def count_dir_files(self, dir): return len([ name for name in os.listdir(dir) if os.path.isfile(os.path.join(dir, name)) ]) def extract_update_progress_count(self, curr, total): txt = str(curr) + "/" + str(total) self.ui.extract_progress_count.setText(txt) self.ui.extract_progress_count.repaint() def extract_update_process(self, output): self.current_frame = count_dir_files(output) - self.old_frames self.current_frame = self.current_frame if self.current_frame > 0 else 0 extract_update_progress_count(self.ui, self.current_frame, self.total_frames) print(self.current_frame, self.total_frames) if self.current_frame >= self.total_frames: for dir in self.ui.fs_watcher.directories(): self.ui.fs_watcher.removePath(dir) print(self.ui.fs_watcher.directories()) self.ui.statusbar.showMessage(self.t('Extraction done')) self.ui.extract_progressbar.setValue(self.current_frame) if self.current_frame > 0: preview(self.ui, self.ui.extract_output_text.text()) def preview(self, dir, order='latest'): glob = Path(dir).glob('*.jpg') if order is 'latest': # find latest image in the folder image_path = next(iter(glob)) for path in glob: if path.stat().st_mtime > image_path.stat().st_mtime: image_path = path elif order is 'random': # choose random image p = list(glob) try: image_path = str(random.choice(p)) except e: print(e) pass else: raise NotImplementedError # Delay preview, let image be fully writen to disk QtCore.QTimer.singleShot(1000, lambda: set_image(self.ui, image_path)) #set_image(self.ui, image_path) def set_image(self, image_path): cvImg = backend.load_image(image_path) if cvImg is None: return label_Image = self.ui.preview_placeholder widget_h = label_Image.height() widget_w = label_Image.width() img_h, img_w, _ = cvImg.shape if img_h > widget_h or img_w > widget_w: ratio = widget_w / img_w new_w = int(img_w * ratio) new_h = int(img_h * ratio) cvImg = cv2.resize(cvImg, (new_w, new_h)) height, width, channel = cvImg.shape bytesPerLine = 3 * width qImg = QtGui.QImage(cvImg, width, height, bytesPerLine, QtGui.QImage.Format_RGB888).rgbSwapped() qImg = QtGui.QPixmap(qImg) label_Image.setPixmap(qImg) app.processEvents() def extract_helper(self): input = self.ui.extract_input_text.text() output = self.ui.extract_output_text.text() p = Path(output) if not p.exists(): os.makedirs(str(p), exist_ok=True) self.old_frames = count_dir_files(output) self.current_frame = 0 self.total_frames = backend.get_frame_count(input) self.ui.extract_progressbar.setMaximum(self.total_frames) extract_update_progress_count(self.ui, self.current_frame, self.total_frames) self.fs_watcher = QtCore.QFileSystemWatcher([output], self.ui.win) self.fs_watcher.directoryChanged.connect( lambda: extract_update_process(self.ui, output)) print(self.ui.win) self.ffmpeg = Process(target=backend.extract_frames, args=(input, output, 'jpg')) self.ffmpeg.start() def process_update_progress_count(self, curr, total): txt = str(curr) + "/" + str(total) self.ui.process_progress_count.setText(txt) self.ui.process_progress_count.repaint() def process_update_process(self, output): self.current_frame = count_dir_files(output) - self.old_frames self.current_frame = self.current_frame if self.current_frame > 0 else 0 process_update_progress_count(self.ui, self.current_frame, self.total_frames) #print(self.current_frame, self.total_frames) if self.current_frame == self.total_frames: for dir in self.fs_watcher.directories(): self.fs_watcher.removePath(dir) self.fs_watcher = None self.statusbar.showMessage(self.t('Processing done')) self.ui.process_progressbar.setValue(self.current_frame) if self.current_frame > 0: preview(self.ui, output) def process_helper(self): input = Path(self.ui.process_input_text.text()) output = Path(input) / 'output' if not output.exists(): os.makedirs(str(output), exist_ok=True) self.ui.statusbar.showMessage(self.t('Starting threads')) self.old_frames = count_dir_files(output) self.current_frame = 0 self.total_frames = count_dir_files( input) - 1 # one is our output folder self.ui.process_progressbar.setMaximum(self.total_frames) process_update_progress_count(self.ui, self.current_frame, self.total_frames) self.fs_watcher = QtCore.QFileSystemWatcher([str(output)], self.ui.win) self.fs_watcher.directoryChanged.connect( lambda: process_update_process(self.ui, output)) #backend.pre_process_folder(input, output, 'cnn') import threading self.masker = Process(target=backend.pre_process_folder, args=(input, output, get_method(self.ui))) #self.ui.win.masker = threading.Thread(target=backend.pre_process_folder, args=(input,output, get_method(self.ui))) self.masker.start() def set_menu_langugage_english(self): print("Englando") self.translator.load('tr_en', os.path.dirname(__file__)) self.ui.retranslateUi(self) self.ui.actionJapanese.setChecked(False) def set_menu_langugage_japanese(self): print("Moshi moshi") self.translator.load('tr_jp', os.path.dirname(__file__)) self.ui.retranslateUi(self) self.ui.actionEnglish.setChecked(False) def t(self, string): return self.app.translate('app', string) def about(self): QMessageBox.about( self, self.t('About Face Masker'), self. t("""This program will help you mask out faces in a video to make it anonymous for future use. This is done by extracting every frame from a video, finding faces in the current frame and mask them out using various methods like pixelating the area, filling it with random noise (recomended) or just simply painting a block box over the face. You can also skip over step one of inputting a video, and provide alreadt extracted frames or independant images you want to mask faces on""" )) def exit(self): sys.exit(self.app.exec_()) def set_up_ui_actions(self): #self.ui.extract_input_text.setText('/Users/axcap/Downloads/input.mp4') #self.ui.extract_output_text.setText('/Users/axcap/Downloads/output') #self.ui.process_input_text.setText('/Users/axcap/Downloads/output') ######## #self.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", self.t('FaceMasker'), None, -1)) self.setWindowTitle( QtWidgets.QApplication.translate("MainWindow", self.t('FaceMasker'), None, -1)) self.ui.extract_button.setFocus() self.ui.process_hog_radioButton.setChecked(True) self.ui.extract_progressbar.setValue(0) self.ui.process_progressbar.setValue(0) self.ui.extract_input_select_button.clicked.connect( lambda: self.extract_select_input( QFileDialog.getOpenFileName(None, self.t( 'Open input video'), '.', self.t('Videos (*.mp4 *.mkv)')))) self.ui.extract_output_select_button.clicked.connect( lambda: self.extract_select_output( QFileDialog.getExistingDirectory(None, self.t('Open Directory' ), '.'))) self.ui.process_input_select_button.clicked.connect( lambda: self.process_select_input( QFileDialog.getExistingDirectory(None, self.t('Open Directory' ), '.'))) self.ui.extract_button.clicked.connect(self.extract_helper) self.ui.process_button.clicked.connect(self.process_helper) # Set menubar actions self.ui.menubar.setNativeMenuBar(False) self.ui.actionExit.triggered.connect(self.exit) self.ui.actionEnglish.triggered.connect( self.set_menu_langugage_english) self.ui.actionJapanese.triggered.connect( self.set_menu_langugage_japanese) self.ui.actionAbout.triggered.connect(self.about)