diff --git a/doc/manual_en_google_translated.docx b/doc/manual_en_google_translated.docx index 9e37138..b1b9834 100644 Binary files a/doc/manual_en_google_translated.docx and b/doc/manual_en_google_translated.docx differ diff --git a/doc/manual_en_google_translated.pdf b/doc/manual_en_google_translated.pdf index b5dd035..4634b9c 100644 Binary files a/doc/manual_en_google_translated.pdf and b/doc/manual_en_google_translated.pdf differ diff --git a/doc/manual_ru.pdf b/doc/manual_ru.pdf index c575b95..6dcc77e 100644 Binary files a/doc/manual_ru.pdf and b/doc/manual_ru.pdf differ diff --git a/doc/manual_ru_source.docx b/doc/manual_ru_source.docx index b63ed7a..de46df9 100644 Binary files a/doc/manual_ru_source.docx and b/doc/manual_ru_source.docx differ diff --git a/interact/interact.py b/interact/interact.py index 7e5c5e9..7ff45f7 100644 --- a/interact/interact.py +++ b/interact/interact.py @@ -134,10 +134,10 @@ class InteractBase(object): self.mouse_events[wnd_name] = [] self.mouse_events[wnd_name] += [ (x, y, ev, flags) ] - def add_key_event(self, wnd_name, key): + def add_key_event(self, wnd_name, ord_key, ctrl_pressed, alt_pressed, shift_pressed): if wnd_name not in self.key_events: self.key_events[wnd_name] = [] - self.key_events[wnd_name] += [ (key,) ] + self.key_events[wnd_name] += [ (ord_key, chr(ord_key), ctrl_pressed, alt_pressed, shift_pressed) ] def get_mouse_events(self, wnd_name): ar = self.mouse_events.get(wnd_name, []) @@ -289,14 +289,19 @@ class InteractDesktop(InteractBase): if has_windows or has_capture_keys: wait_key_time = max(1, int(sleep_time*1000) ) - key = cv2.waitKey(wait_key_time) & 0xFF + ord_key = cv2.waitKey(wait_key_time) + shift_pressed = False + if ord_key != -1: + if chr(ord_key) >= 'A' and chr(ord_key) <= 'Z': + shift_pressed = True + ord_key += 32 else: if sleep_time != 0: time.sleep(sleep_time) - if has_capture_keys and key != 255: + if has_capture_keys and ord_key != -1: for wnd_name in self.capture_keys_windows: - self.add_key_event (wnd_name, key) + self.add_key_event (wnd_name, ord_key, False, False, shift_pressed) def on_wait_any_key(self): cv2.waitKey(0) diff --git a/main.py b/main.py index f7d77ae..5f210d6 100644 --- a/main.py +++ b/main.py @@ -17,12 +17,11 @@ class fixPathAction(argparse.Action): if __name__ == "__main__": multiprocessing.set_start_method("spawn") - os_utils.set_process_lowest_prio() parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers() def process_extract(arguments): + os_utils.set_process_lowest_prio() from mainscripts import Extractor Extractor.main( arguments.input_dir, arguments.output_dir, @@ -51,6 +50,7 @@ if __name__ == "__main__": p.set_defaults (func=process_extract) def process_sort(arguments): + os_utils.set_process_lowest_prio() from mainscripts import Sorter Sorter.main (input_path=arguments.input_dir, sort_by_method=arguments.sort_by_method) @@ -60,6 +60,7 @@ if __name__ == "__main__": p.set_defaults (func=process_sort) def process_util(arguments): + os_utils.set_process_lowest_prio() from mainscripts import Util if arguments.convert_png_to_jpg: @@ -79,6 +80,7 @@ if __name__ == "__main__": p.set_defaults (func=process_util) def process_train(arguments): + os_utils.set_process_lowest_prio() args = {'training_data_src_dir' : arguments.training_data_src_dir, 'training_data_dst_dir' : arguments.training_data_dst_dir, 'model_path' : arguments.model_dir, @@ -106,6 +108,7 @@ if __name__ == "__main__": p.set_defaults (func=process_train) def process_convert(arguments): + os_utils.set_process_lowest_prio() args = {'input_dir' : arguments.input_dir, 'output_dir' : arguments.output_dir, 'aligned_dir' : arguments.aligned_dir, @@ -133,6 +136,7 @@ if __name__ == "__main__": videoed_parser = subparsers.add_parser( "videoed", help="Video processing.").add_subparsers() def process_videoed_extract_video(arguments): + os_utils.set_process_lowest_prio() from mainscripts import VideoEd VideoEd.extract_video (arguments.input_file, arguments.output_dir, arguments.output_ext, arguments.fps) p = videoed_parser.add_parser( "extract-video", help="Extract images from video file.") @@ -143,6 +147,7 @@ if __name__ == "__main__": p.set_defaults(func=process_videoed_extract_video) def process_videoed_cut_video(arguments): + os_utils.set_process_lowest_prio() from mainscripts import VideoEd VideoEd.cut_video (arguments.input_file, arguments.from_time, @@ -158,6 +163,7 @@ if __name__ == "__main__": p.set_defaults(func=process_videoed_cut_video) def process_videoed_denoise_image_sequence(arguments): + os_utils.set_process_lowest_prio() from mainscripts import VideoEd VideoEd.denoise_image_sequence (arguments.input_dir, arguments.ext, arguments.factor) p = videoed_parser.add_parser( "denoise-image-sequence", help="Denoise sequence of images, keeping sharp edges. This allows you to make the final fake more believable, since the neural network is not able to make a detailed skin texture, but it makes the edges quite clear. Therefore, if the whole frame is more `blurred`, then a fake will seem more believable. Especially true for scenes of the film, which are usually very clear.") @@ -167,6 +173,7 @@ if __name__ == "__main__": p.set_defaults(func=process_videoed_denoise_image_sequence) def process_videoed_video_from_sequence(arguments): + os_utils.set_process_lowest_prio() from mainscripts import VideoEd VideoEd.video_from_sequence (arguments.input_dir, arguments.output_file, diff --git a/mainscripts/Extractor.py b/mainscripts/Extractor.py index ab1023f..9e1055d 100644 --- a/mainscripts/Extractor.py +++ b/mainscripts/Extractor.py @@ -411,7 +411,7 @@ class ExtractSubprocessor(Subprocessor): new_y = np.clip (y, 0, h-1) / self.view_scale key_events = io.get_key_events(self.wnd_name) - key, = key_events[-1] if len(key_events) > 0 else (0,) + key, chr_key, ctrl_pressed, alt_pressed, shift_pressed = key_events[-1] if len(key_events) > 0 else (0,0,False,False,False) if key == ord('\r') or key == ord('\n'): #confirm frame diff --git a/mainscripts/MaskEditorTool.py b/mainscripts/MaskEditorTool.py index deb2f25..173e73f 100644 --- a/mainscripts/MaskEditorTool.py +++ b/mainscripts/MaskEditorTool.py @@ -46,9 +46,11 @@ class MaskEditor: self.polys_mask = None + self.mouse_x = self.mouse_y = 9999 self.screen_status_block = None self.screen_status_block_dirty = True - + self.screen_changed = True + def set_state(self, state): self.state = state @@ -175,10 +177,12 @@ class MaskEditor: def set_screen_status_block_dirty(self): self.screen_status_block_dirty = True + def switch_screen_changed(self): + result = self.screen_changed + self.screen_changed = False + return result + def make_screen(self): - - - screen_overlay = self.get_screen_overlay() final_mask = self.get_mask() @@ -201,6 +205,7 @@ class MaskEditor: def mask_finish(self, n_clip=True): if self.state == self.STATE_MASKING: + self.screen_changed = True if self.ie_polys.n_list().n <= 2: self.ie_polys.n_dec() self.state = self.STATE_NONE @@ -210,10 +215,13 @@ class MaskEditor: def set_mouse_pos(self,x,y): mouse_x = x % (self.sw) - self.pw mouse_y = y % (self.sh) - self.ph - self.mouse_xy = np.array( [mouse_x, mouse_y] ) - self.mouse_x, self.mouse_y = self.mouse_xy + if mouse_x != self.mouse_x and mouse_y != self.mouse_y: + self.mouse_xy = np.array( [mouse_x, mouse_y] ) + self.mouse_x, self.mouse_y = self.mouse_xy + self.screen_changed = True def mask_point(self, type): + self.screen_changed = True if self.state == self.STATE_MASKING and \ self.ie_polys.n_list().type != type: self.mask_finish() @@ -252,9 +260,12 @@ def mask_editor_main(input_dir, confirmed_dir=None, skipped_dir=None): done_paths = [] image_paths_total = len(image_paths) - - - + + do_prev_count = 0 + do_save_move_count = 0 + do_save_count = 0 + do_skip_move_count = 0 + do_skip_count = 0 is_exit = False while not is_exit: @@ -294,6 +305,7 @@ def mask_editor_main(input_dir, confirmed_dir=None, skipped_dir=None): '[Mouse wheel] - undo/redo poly or point. [+ctrl] - undo to begin/redo to end', '[q] - prev image. [w] - skip and move to %s. [e] - save and move to %s. ' % (skipped_path.name, confirmed_path.name), '[z] - prev image. [x] - skip. [c] - save. ', + 'hold [shift] - speed up the frame counter by 10.' '[esc] - quit' ] ed = MaskEditor(img, mask, ie_polys, get_status_lines_func) @@ -301,75 +313,101 @@ def mask_editor_main(input_dir, confirmed_dir=None, skipped_dir=None): next = False while not next: io.process_messages(0.005) - - for (x,y,ev,flags) in io.get_mouse_events(wnd_name): - ed.set_mouse_pos(x, y) - if filepath is not None: - if ev == io.EVENT_LBUTTONDOWN: - ed.mask_point(1) - elif ev == io.EVENT_RBUTTONDOWN: - ed.mask_point(0) - elif ev == io.EVENT_MBUTTONDOWN: - ed.mask_finish() - elif ev == io.EVENT_MOUSEWHEEL: - if flags & 0x80000000 != 0: - if flags & 0x8 != 0: - ed.undo_to_begin_point() + + if do_prev_count + do_save_move_count + do_save_count + do_skip_move_count + do_skip_count == 0: + for (x,y,ev,flags) in io.get_mouse_events(wnd_name): + ed.set_mouse_pos(x, y) + if filepath is not None: + if ev == io.EVENT_LBUTTONDOWN: + ed.mask_point(1) + elif ev == io.EVENT_RBUTTONDOWN: + ed.mask_point(0) + elif ev == io.EVENT_MBUTTONDOWN: + ed.mask_finish() + elif ev == io.EVENT_MOUSEWHEEL: + if flags & 0x80000000 != 0: + if flags & 0x8 != 0: + ed.undo_to_begin_point() + else: + ed.undo_point() else: - ed.undo_point() - else: - if flags & 0x8 != 0: - ed.redo_to_end_point() - else: - ed.redo_point() + if flags & 0x8 != 0: + ed.redo_to_end_point() + else: + ed.redo_point() - key_events = [ ev for ev, in io.get_key_events(wnd_name) ] - for key in key_events: - if key == ord('q') or key == ord('z'): - if len(done_paths) > 0: - image_paths.insert(0, filepath) - filepath = done_paths.pop(-1) - - if filepath.parent != input_path: - new_filename_path = input_path / filepath.name - filepath.rename ( new_filename_path ) - image_paths.insert(0, new_filename_path) - else: - image_paths.insert(0, filepath) - + for key, chr_key, ctrl_pressed, alt_pressed, shift_pressed in io.get_key_events(wnd_name): + if chr_key == 'q' or chr_key == 'z': + do_prev_count = 1 if not shift_pressed else 10 + elif key == 27: #esc + is_exit = True next = True break - elif filepath is not None and ( key == ord('e') or key == ord('c') ): + elif filepath is not None: + if chr_key == 'e': + do_save_move_count = 1 if not shift_pressed else 10 + elif chr_key == 'c': + do_save_count = 1 if not shift_pressed else 10 + elif chr_key == 'w': + do_skip_move_count = 1 if not shift_pressed else 10 + elif chr_key == 'x': + do_skip_count = 1 if not shift_pressed else 10 + + if do_prev_count > 0: + do_prev_count -= 1 + if len(done_paths) > 0: + image_paths.insert(0, filepath) + filepath = done_paths.pop(-1) + + if filepath.parent != input_path: + new_filename_path = input_path / filepath.name + filepath.rename ( new_filename_path ) + image_paths.insert(0, new_filename_path) + else: + image_paths.insert(0, filepath) + + next = True + elif filepath is not None: + if do_save_move_count > 0: + do_save_move_count -= 1 + + ed.mask_finish() + dflimg.embed_and_set (str(filepath), ie_polys=ed.get_ie_polys() ) + + done_paths += [ confirmed_path / filepath.name ] + filepath.rename(done_paths[-1]) + + next = True + elif do_save_count > 0: + do_save_count -= 1 + ed.mask_finish() dflimg.embed_and_set (str(filepath), ie_polys=ed.get_ie_polys() ) - if key == ord('e'): - new_filename_path = confirmed_path / filepath.name - filepath.rename(new_filename_path) - done_paths += [new_filename_path] - else: - done_paths += [filepath] + done_paths += [filepath] + next = True + elif do_skip_move_count > 0: + do_skip_move_count -= 1 + + done_paths += [skipped_path / filepath.name] + filepath.rename(done_paths[-1]) + + next = True + elif do_skip_count > 0: + do_skip_count -= 1 + + done_paths += [filepath] + next = True - break + else: + do_save_move_count = do_save_count = do_skip_move_count = do_skip_count = 0 - elif filepath is not None and ( key == ord('w') or key == ord('x') ): - if key == ord('w'): - new_filename_path = skipped_path / filepath.name - filepath.rename(new_filename_path) - done_paths += [new_filename_path] - else: - done_paths += [filepath] - - next = True - break - elif key == 27: #esc - is_exit = True - next = True - break - screen = ed.make_screen() + if do_prev_count + do_save_move_count + do_save_count + do_skip_move_count + do_skip_count == 0: + if ed.switch_screen_changed(): + io.show_image (wnd_name, ed.make_screen() ) - io.show_image (wnd_name, screen ) + io.process_messages(0.005) io.destroy_all_windows() diff --git a/mainscripts/Trainer.py b/mainscripts/Trainer.py index 5bbdaf5..25eff5b 100644 --- a/mainscripts/Trainer.py +++ b/mainscripts/Trainer.py @@ -273,8 +273,8 @@ def main(args, device_args): is_showing = True key_events = io.get_key_events(wnd_name) - key, = key_events[-1] if len(key_events) > 0 else (0,) - + key, chr_key, ctrl_pressed, alt_pressed, shift_pressed = key_events[-1] if len(key_events) > 0 else (0,0,False,False,False) + if key == ord('\n') or key == ord('\r'): s2c.put ( {'op': 'close'} ) elif key == ord('s'):