Reputation: 1037
I'm at a loss for what is happening here. I'm trying to run an opencv VideoCapture process to read frames and put on a Queue for workers to process.
The application never finishes running because the CameraProcess instance never seems to terminate. After a little investigation, it looks like the camera is reported as closed after a call to #release(), but is considered open on the main process.
Should I not be creating a VideoCapture instance from within the Process?
Sample Application:
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()
Application Output:
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
Environment:
Upvotes: 1
Views: 1241
Reputation: 18341
Strangely, it should be released. But the camera resource is still being occupied. May be it's a bug? Or maybe it's something new to new ...
To release the resource correctly, I define a new method as follow. Then it works.
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()
The result is OK
now.
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
Upvotes: 3