I’m learning python as I go and am currently implementing multiprocessing but I cannot successfully exit the app I’ve written. It seems the ‘capture_read_frame_process’ process just doesn’t end and I cannot see why. Any pointers here would be appreicated.
import cv2 as cv
import multiprocessing
class Camera(object):
def __init__(self, source):
self._source = source
self.image_queue = multiprocessing.Queue()
match self._source:
case 'cam':
self._source_url = 0
self._apiPref = cv.CAP_DSHOW
case 'boysr':
self._source_url = 'rtsps://192.168.1.1:7441/xhw7D6R7BR8NP5vg'
self._apiPref = cv.CAP_FFMPEG
case 'frontd':
self._source_url = 'rtsps://192.168.1.1:7441/EOEohGh0eoXIWf28'
self._apiPref = cv.CAP_FFMPEG
case 'video':
self._source_url = 'event.mp4'
self._apiPref = cv.CAP_FFMPEG
def read_frames(self, queue, stop_read):
self.query_source = cv.VideoCapture(self._source_url, self._apiPref)
self.query_source.set(cv.CAP_PROP_BUFFERSIZE, 1)
self.query_source.set(cv.CAP_PROP_FPS, 20)
if self.query_source.isOpened():
print('Capture object successfully started')
else:
raise Exception('Unable to start capture object')
_failFrame = 0
while not stop_read.is_set():
_hasFrame, _query_image = self.query_source.read()
if not _hasFrame:
_failFrame += 1
if _failFrame == 15:
raise Exception(f"Failed to grab a frame after {_failFrame} consequtive tries")
continue
else:
_failFrame = 0
queue.put(_query_image)
self.query_source.release()
def show_frame(self, queue, stop_read):
while True:
_query_image = queue.get()
cv.imshow('autoface', _query_image)
if cv.waitKey(1) == ord('q'):
cv.destroyAllWindows()
break
if __name__ == '__main__':
print('Starting capture object')
capture = Camera('cam')
# Create the event to use to stop the program
stop_read = multiprocessing.Event()
print('Starting read_frames process')
capture_read_frame_process = multiprocessing.Process(target=capture.read_frames, args=(capture.image_queue, stop_read,))
capture_read_frame_process.start()
print('Starting show_frames process')
capture_show_frame_process = multiprocessing.Process(target=capture.show_frame, args=(capture.image_queue, stop_read,))
capture_show_frame_process.start()
capture_show_frame_process.join() # Should complete when 'q' is typed when the cv.imshow window is open and active.
stop_read.set() # This should then break the loop in the read_frames function of the Camera object
capture_read_frame_process.join()
print('nProgram exited')
When the image is displayed on screen pressing ‘q’ should close the window and cause the program to exit. It does close the window but the code never gets past the ‘capture_read_frame_process.join()’ statement.