Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python OpenCV和自定义多处理_Python_Multithreading_Opencv - Fatal编程技术网

Python OpenCV和自定义多处理

Python OpenCV和自定义多处理,python,multithreading,opencv,Python,Multithreading,Opencv,我尝试构建一个网络摄像头软件,它使用网络摄像头输入并更改图像,然后将其输出到虚拟网络摄像头。所以我让它运行得很好,但现在我想添加一个系统托盘图标来控制它。由于这是一个GUI,我需要我的软件在另一个线程上运行 因此,我的(削减)类看起来如下: import pyvirtualcam import cv2 import effects import numpy as np class VirtualCam: def __init__(self): self.stoppe

我尝试构建一个网络摄像头软件,它使用网络摄像头输入并更改图像,然后将其输出到虚拟网络摄像头。所以我让它运行得很好,但现在我想添加一个系统托盘图标来控制它。由于这是一个GUI,我需要我的软件在另一个线程上运行

因此,我的(削减)类看起来如下:

import pyvirtualcam
import cv2
import effects
import numpy as np


class VirtualCam:

    def __init__(self):
        self.stopped = False
        self.paused = False
        [...]

    def run(self):
        with pyvirtualcam.Camera(width=1280, height=720, fps=self.FPS, fmt=pyvirtualcam.PixelFormat.BGR) as cam:
            while not self.stopped:
                if not self.paused:  # only copy image if NOT paused!
                    success, img = self.cap.read()
                else:
                    img = self.EMPTY_IMAGE

                cam.send(effects.zoom(img, self.zoom))
                cam.sleep_until_next_frame()
所以这应该是直截了当的。 现在,在基于代码的gui线程上,我添加了菜单点,其中一个启动一个线程,而其他线程可以暂停、停止等(再次减少):

好吧,这应该行得通,不是吗?当我点击托盘菜单中的“开始”时,我得到一个错误:

Python WNDPROC handler failed
Traceback (most recent call last):
  File "I:/Entwicklung/webcamZoomer/tray_gui.py", line 207, in command
    self.execute_menu_option(id)
  File "I:/Entwicklung/webcamZoomer/tray_gui.py", line 214, in execute_menu_option
    menu_action(self)
  File "I:/Entwicklung/webcamZoomer/tray_gui.py", line 256, in start
    cam_thread.start()
  File "H:\Programme\Python3\lib\multiprocessing\process.py", line 112, in start
    self._popen = self._Popen(self)
  File "H:\Programme\Python3\lib\multiprocessing\context.py", line 223, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "H:\Programme\Python3\lib\multiprocessing\context.py", line 322, in _Popen
    return Popen(process_obj)
  File "H:\Programme\Python3\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
    reduction.dump(process_obj, to_child)
  File "H:\Programme\Python3\lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle cv2.VideoCapture objects
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "H:\Programme\Python3\lib\multiprocessing\spawn.py", line 105, in spawn_main
    exitcode = _main(fd)
  File "H:\Programme\Python3\lib\multiprocessing\spawn.py", line 115, in _main
    self = reduction.pickle.load(from_parent)
EOFError: Ran out of input
Python WNDPROC处理程序失败
回溯(最近一次呼叫最后一次):
命令中第207行的文件“I:/Entwicklung/webcamZoomer/tray_gui.py”
self.execute\u菜单\u选项(id)
文件“I:/Entwicklung/webcamZoomer/tray\u gui.py”,第214行,在执行菜单选项中
菜单动作(自我)
文件“I:/Entwicklung/webcamZoomer/tray_gui.py”,第256行,开头
cam_thread.start()
文件“H:\Program\Python3\lib\multiprocessing\process.py”,第112行,在开始处
self.\u popen=self.\u popen(self)
文件“H:\program\Python3\lib\multiprocessing\context.py”,第223行,在\u Popen中
返回_default_context.get_context().Process._Popen(Process_obj)
文件“H:\program\Python3\lib\multiprocessing\context.py”,第322行,在\u Popen中
返回Popen(过程对象)
文件“H:\program\Python3\lib\multiprocessing\popen\u spawn\u win32.py”,第65行,在\uuu init中__
减少.转储(进程对象,到子进程)
文件“H:\Program\Python3\lib\multiprocessing\reduce.py”,第60行,在转储中
ForkingPickler(文件、协议).dump(obj)
TypeError:无法pickle cv2.VideoCapture对象
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“H:\Program\Python3\lib\multiprocessing\spawn.py”,第105行,在spawn\u main中
出口代码=_主(fd)
文件“H:\Program\Python3\lib\multiprocessing\spawn.py”,第115行,在_main中
self=reduce.pickle.load(从父级)
EOFError:输入不足

当然,我使用了搜索功能,但我只能找到一些我并不真正理解的东西:似乎OpenCV已经使用了多处理。但为什么它会干扰我的代码?此外,我不做任何手工酸洗;我实际上只需要网络摄像头的输入

有人能帮我解决这个问题吗?谢谢大家!


编辑:顺便说一句,我在Windows 10上,我只需要在Windows系统上使用此软件。

“我不做任何手动酸洗”--不,但您启动一个新进程,并希望它运行您在原始进程中实例化的对象的方法。为了能够做到这一点,Python必须将该对象实例转移到第二个进程。要做到这一点,它必须通过队列发送,而要做到这一点,它需要对其进行酸洗您没有显示它,但我看到一个
self.cap.read()
,因此
VirtualCam
确实有一个
VideoCapture
成员(很可能已经打开)。即使可以通过某种方式对其进行腌制和传输,您也会有两个进程试图访问同一个网络摄像头(这是行不通的)@DanMašek谢谢,我现在明白了问题所在。现在我不应该在gui线程中创建实例了吗?如果没有,我如何访问实例来操作我想在virtualcam上使用的设置?您必须确保
VideoCapture
(以及可能的其他对象)仅在第二个过程中实例化,并且您需要设置一些IPC机制(例如队列)将图像数据传输到主进程,并将命令传输到捕获进程IMHO多处理是一个不必要的复杂问题。OpenCV和许多numpy函数释放了GIL,因此在许多情况下,您只需使用
线程
。例如,查看(有一条注释带有指向pastebin的链接,其中包含最终代码)。
Python WNDPROC handler failed
Traceback (most recent call last):
  File "I:/Entwicklung/webcamZoomer/tray_gui.py", line 207, in command
    self.execute_menu_option(id)
  File "I:/Entwicklung/webcamZoomer/tray_gui.py", line 214, in execute_menu_option
    menu_action(self)
  File "I:/Entwicklung/webcamZoomer/tray_gui.py", line 256, in start
    cam_thread.start()
  File "H:\Programme\Python3\lib\multiprocessing\process.py", line 112, in start
    self._popen = self._Popen(self)
  File "H:\Programme\Python3\lib\multiprocessing\context.py", line 223, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "H:\Programme\Python3\lib\multiprocessing\context.py", line 322, in _Popen
    return Popen(process_obj)
  File "H:\Programme\Python3\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
    reduction.dump(process_obj, to_child)
  File "H:\Programme\Python3\lib\multiprocessing\reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle cv2.VideoCapture objects
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "H:\Programme\Python3\lib\multiprocessing\spawn.py", line 105, in spawn_main
    exitcode = _main(fd)
  File "H:\Programme\Python3\lib\multiprocessing\spawn.py", line 115, in _main
    self = reduction.pickle.load(from_parent)
EOFError: Ran out of input