From d30b7ecd98ad8a679297e6ef6c44eb15f87a5427 Mon Sep 17 00:00:00 2001 From: Emiliana <38952746+emilianavt@users.noreply.github.com> Date: Tue, 11 Aug 2020 12:10:39 +0200 Subject: [PATCH] Added redistributable DLLs to binary builds and improved camera reinitialization. --- facetracker.py | 4 ++++ facetracker.spec | 2 +- input_reader.py | 23 ++++++++++++++++++----- make_exe.bat | 8 ++++++++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/facetracker.py b/facetracker.py index e794368..ec6f06b 100644 --- a/facetracker.py +++ b/facetracker.py @@ -116,9 +116,13 @@ try: target_duration = 1. / float(fps) repeat = args.repeat_video != 0 and type(input_reader.reader) == VideoReader need_reinit = 0 + source_name = input_reader.name while repeat or input_reader.is_open(): if not input_reader.is_open() or need_reinit == 1: input_reader = InputReader(args.capture, args.raw_rgb, args.width, args.height, fps, use_dshowcapture=use_dshowcapture_flag) + if input_reader.name != source_name: + print(f"Failed to reinitialize camera and got {input_reader.name} instead of {source_name}.") + sys.exit(1) need_reinit = 2 time.sleep(0.02) continue diff --git a/facetracker.spec b/facetracker.spec index a62d869..6689363 100644 --- a/facetracker.spec +++ b/facetracker.spec @@ -5,7 +5,7 @@ block_cipher = None a = Analysis(['facetracker.py'], pathex=['C:\\OpenSeeFaceBuild'], - binaries=[('dshowcapture/dshowcapture_x86.dll', '.'), ('dshowcapture/dshowcapture_x64.dll', '.'), ('escapi/escapi_x86.dll', '.'), ('escapi/escapi_x64.dll', '.'), ('run.bat', '.')], + binaries=[('dshowcapture/dshowcapture_x86.dll', '.'), ('dshowcapture/dshowcapture_x64.dll', '.'), ('escapi/escapi_x86.dll', '.'), ('escapi/escapi_x64.dll', '.'), ('run.bat', '.'), ('c:/windows/system32/msvcp140.dll', '.'), ('c:/windows/system32/vcomp140.dll', '.'), ('c:/windows/system32/concrt140.dll', '.'), ('c:/windows/system32/vccorlib140.dll', '.')], datas=[], hiddenimports=[], hookspath=[], diff --git a/input_reader.py b/input_reader.py index 9a0b8f4..b608a0f 100644 --- a/input_reader.py +++ b/input_reader.py @@ -17,6 +17,7 @@ class VideoReader(): if self.cap is None: print("The video source cannot be opened") sys.exit(0) + self.name = str(capture) def is_open(self): return self.cap.isOpened() def is_ready(self): @@ -33,6 +34,8 @@ class EscapiReader(VideoReader): self.height = height self.fps = fps self.device = capture + escapi.count_capture_devices() + self.name = str(escapi.device_name(self.device).decode('utf8')) self.buffer = escapi.init_camera(self.device, self.width, self.height, self.fps) escapi.do_capture(self.device) def is_open(self): @@ -57,7 +60,7 @@ class DShowCaptureReader(VideoReader): self.fps = fps self.device = dshowcapture.DShowCapture() self.device.get_devices() - self.device_name = self.device.get_device(capture) + self.name = self.device.get_device(capture) self.device.capture_device(capture, self.width, self.height, self.fps) self.timeout = 1000 def is_open(self): @@ -79,6 +82,7 @@ class OpenCVReader(VideoReader): self.width = width self.height = height self.fps = fps + self.name = str(capture) super(OpenCVReader, self).__init__(capture, camera=True) self.cap.set(3, width) self.cap.set(4, height) @@ -124,7 +128,7 @@ def try_int(s): return None def test_reader(reader): - got_any = False + got_any = 0 try: for i in range(30): if not reader.is_ready(): @@ -135,9 +139,11 @@ def test_reader(reader): print("No frame") else: print("Got frame") - got_any = True + got_any += 1 + if got_any > 10: + break if reader.is_open(): - return got_any + return got_any > 0 print("Fail") return False except: @@ -148,6 +154,7 @@ def test_reader(reader): class InputReader(): def __init__(self, capture, raw_rgb, width, height, fps, use_dshowcapture=False): self.reader = None + self.name = str(capture) try: if raw_rgb > 0: self.reader = RawReader(width, height) @@ -161,11 +168,14 @@ class InputReader(): try: if use_dshowcapture: self.reader = DShowCaptureReader(int(capture), width, height, fps) - name = self.reader.device_name + name = self.reader.name good = test_reader(self.reader) + self.name = name else: good = False except: + print("DShowCapture exception: ") + traceback.print_exc() good = False if good: return @@ -187,12 +197,15 @@ class InputReader(): self.reader = EscapiReader(found, width, height, fps) good = test_reader(self.reader) except: + print("Escapi exception: ") + traceback.print_exc() good = False if good: return # Try with OpenCV print(f"Escapi failed. Falling back to OpenCV. If this fails, please change your camera settings.", file=sys.stderr) self.reader = OpenCVReader(int(capture), width, height, fps) + self.name = self.reader.name else: self.reader = OpenCVReader(int(capture), width, height, fps) except Exception as e: diff --git a/make_exe.bat b/make_exe.bat index e3a8b4d..8e436ae 100644 --- a/make_exe.bat +++ b/make_exe.bat @@ -3,6 +3,10 @@ REM --add-binary dshowcapture/dshowcapture_x86.dll;. ^ REM --add-binary dshowcapture/dshowcapture_x64.dll;. ^ REM --add-binary escapi/escapi_x86.dll;. ^ REM --add-binary escapi/escapi_x64.dll;. ^ +REM --add-binary msvcp140.dll;. ^ +REM --add-binary vcomp140.dll;. ^ +REM --add-binary concrt140.dll;. ^ +REM --add-binary vccorlib140.dll;. ^ REM --add-binary run.bat;. pyinstaller facetracker.spec --onedir ^ @@ -10,6 +14,10 @@ pyinstaller facetracker.spec --onedir ^ --add-binary dshowcapture/dshowcapture_x64.dll;. ^ --add-binary escapi/escapi_x86.dll;. ^ --add-binary escapi/escapi_x64.dll;. ^ + --add-binary msvcp140.dll;. ^ + --add-binary vcomp140.dll;. ^ + --add-binary concrt140.dll;. ^ + --add-binary vccorlib140.dll;. ^ --add-binary run.bat;. del dist\facetracker\cv2\opencv_videoio_ffmpeg420_64.dll