如何终止" multiprocessing.Process"正确使用" cv2.VideoCapture" (Python OpenCV)?

时间:2018-01-11 22:39:04

标签: python opencv multiprocessing

我对这里发生的事情感到茫然。我试图运行一个opencv VideoCapture进程来读取帧并放入一个队列供工人处理。

应用程序永远不会运行,因为CameraProcess实例似乎永远不会终止。经过一些调查后,看起来在调用#release()后相机报告已关闭,但在主进程中被视为打开。

我不应该在Process中创建一个VideoCapture实例吗?

示例应用程序:

import cv2
from multiprocessing import Process, Event
from time import sleep

class CameraProcess(Process):
    def __init__(self, camera_id, *args, **kwargs):
        super(CameraProcess, self).__init__(*args, **kwargs)
        self.shutdown = Event()

        self.camera = cv2.VideoCapture(camera_id)
        sleep(1)
        print('Camera is opened? {}'.format(self.camera.isOpened()))

    def run(self):
        while not self.shutdown.wait(0.05):
            print('Doing camera stuff')
            sleep(1)

        self.camera.release()
        print('Camera is closed? {}'.format(not self.camera.isOpened()))

try:
    camera = CameraProcess(0)
    camera.start()
    sleep(5)
    camera.shutdown.set()
    sleep(2)
    print('Camera is closed? {}'.format(not camera.camera.isOpened()))
except KeyboardInterrupt:
    pass
finally:
    camera.terminate()

应用程序输出:

Camera is opened? True
Doing camera stuff
Doing camera stuff
Doing camera stuff
Doing camera stuff
Doing camera stuff
Camera is closed? True
Camera is closed? False

环境:

  • Debian stretch
  • Python:3.5.3
  • cv2:3.4.0

1 个答案:

答案 0 :(得分:2)

奇怪的是,它应该被释放。但相机资源仍在被占用。可能是一个错误?或者它可能是新的......

为了正确释放资源,我定义了一个新方法,如下所示。然后就行了。

import cv2
from multiprocessing import Process, Event
from time import sleep

class CameraProcess(Process):
    def __init__(self, camera_id, *args, **kwargs):
        super(CameraProcess, self).__init__(*args, **kwargs)
        self.shutdown = Event()

        self.camera = cv2.VideoCapture(camera_id)
        print('Camera is opened? {}'.format(self.camera.isOpened()))

    def run(self):
        while not self.shutdown.wait(0.05):
            print('Doing camera stuff')
            sleep(1)
        self.camera.release()
        print('[run   ] Camera is closed? {}'.format(not self.camera.isOpened()))

    ## Defind a new method to release the resourse(again).
    def shutup(self):
        self.shutdown.set()
        if self.camera.isOpened():
            self.camera.release()
        print('[shutup] Camera is closed? {}'.format(not self.camera.isOpened()))

try:
    camera = CameraProcess(0)
    camera.start()
    sleep(5)
    camera.shutup()
    sleep(2)
    print('[main  ] Camera is closed? {}'.format(not camera.camera.isOpened()))
except KeyboardInterrupt:
    pass
finally:
    camera.terminate()

现在结果为OK

Camera is opened? True
Doing camera stuff
Doing camera stuff
Doing camera stuff
Doing camera stuff
Doing camera stuff
[shutup] Camera is closed? True
[run   ] Camera is closed? True
[main  ] Camera is closed? True