[FIXED] Does the thread can terminate when call OpenCV release() method?

Issue

The ThreadedCamera Class that get frame from thread.

I have two questions.

Q1: Will it affect program performance if I don’t close threads when I create a lot of ThreadedCamera classes?

Q2: Does the thread can terminate when call __del__ method?

from threading import Thread
import cv2, time

class ThreadedCamera(object):
    def __init__(self, src=0):
        self.capture = cv2.VideoCapture(src)
        
        # Start frame retrieval thread
        self.thread = Thread(target=self.update, args=())
        self.thread.daemon = True
        self.thread.start()
        
    def update(self):
        while True:
            if self.capture.isOpened():
                (self.status, self.frame) = self.capture.read()
            
    def get_frame(self):
        return self.frame
    
    def __del__(self): # Q2: Does the self.thread can terminate when call this method ? 
        self.capture.release()

Solution

  1. It is always a good idea to cleanup resources and joining threads. However, since the camera thread is deamon, it will be closed when the calling thread terminates. A more traditional way is to use a threading.Event to trigger the while loop breaking and thread termination.
  2. Why not simply create a graceful shutdown method where everything is cleaned up when you want to? I don’t really like playing with core dunder methods like __del__.
import cv2
import threading 
import time

class ThreadedCamera:
    
    def __init__(self, src=0):
        self.capture = cv2.VideoCapture(src)
        self.terminate_camera_thread = threading.Event()
        self.thread = threading.Thread(target=self.update, daemon=True)
        self.thread.start()
    
    def update(self):
        while not self.terminate_camera_thread.is_set():
            if self.capture.isOpened():
               (self.status, self.frame) = self.capture.read()

    def shutdown(self):
        self.terminate_camera_thread.set()
        self.capture.release()

You can automate this cleaning with context managers so you can use with:


with ThreadedCamera() as camera:

    # camera processing for loop

by adding

def __enter__(self):
    return self

def __exit__(self, *args, **kwargs):
    self.shutdown()

Answered By – SystemSigma_

Answer Checked By – Gilberto Lyons (Easybugfix Admin)

Leave a Reply

(*) Required, Your email will not be published