线程是进程中的一个执行单元。多线程是指通过在线程之间快速切换对 CPU 的控制来并发执行多个线程。
在Python中,我们通常使用threading库对线程来进行控制。
在没有多线程的程序中按顺序进行处理时,程序等待下一帧可用,然后再对其进行处理。读取帧所需的时间主要与请求、等待和将下一个视频帧从相机传输到内存所需的时间有关。对视频帧进行计算所花费的时间,无论是在 CPU 还是 GPU 上,占据了视频处理所花费的大部分时间。
多线程可以运用在深度学习中的图像识别,例如:利用视频流进行目标检测、实时的语义分割以及人脸识别等等。
下例程序运行后,在英文输入法下按q即可结束运行。代码来自于https://github.com/SihabSahariar/Multi-threading-OpenCV-
# importing required libraries
import cv2
import time
from threading import Thread # library for implementing multi-threaded processing
# defining a helper class for implementing multi-threaded processing
class WebcamStream :
def __init__(self, stream_id=0):
self.stream_id = stream_id # default is 0 for primary camera
# opening video capture stream
self.vcap = cv2.VideoCapture(self.stream_id)
if self.vcap.isOpened() is False :
print("[Exiting]: Error accessing webcam stream.")
exit(0)
fps_input_stream = int(self.vcap.get(5))
print("FPS of webcam hardware/input stream: {}".format(fps_input_stream))
# reading a single frame from vcap stream for initializing
self.grabbed , self.frame = self.vcap.read()
if self.grabbed is False :
print('[Exiting] No more frames to read')
exit(0)
# self.stopped is set to False when frames are being read from self.vcap stream
self.stopped = True
# reference to the thread for reading next available frame from input stream
self.t = Thread(target=self.update, args=())
self.t.daemon = True # daemon threads keep running in the background while the program is executing
# method for starting the thread for grabbing next available frame in input stream
def start(self):
self.stopped = False
self.t.start()
# method for reading next frame
def update(self):
while True :
if self.stopped is True :
break
self.grabbed , self.frame = self.vcap.read()
if self.grabbed is False :
print('[Exiting] No more frames to read')
self.stopped = True
break
self.vcap.release()
# method for returning latest read frame
def read(self):
return self.frame
# method called to stop reading frames
def stop(self):
self.stopped = True
# initializing and starting multi-threaded webcam capture input stream
webcam_stream = WebcamStream(stream_id=0) # stream_id = 0 is for primary camera
webcam_stream.start()
# processing frames in input stream
num_frames_processed = 0
start = time.time()
while True :
if webcam_stream.stopped is True :
break
else :
frame = webcam_stream.read()
# adding a delay for simulating time taken for processing a frame
delay = 0.03 # delay value in seconds. so, delay=1 is equivalent to 1 second
time.sleep(delay)
num_frames_processed += 1
cv2.imshow('frame' , frame)
key = cv2.waitKey(1)
if key == ord('q'):
break
end = time.time()
webcam_stream.stop() # stop the webcam stream
# printing time elapsed and fps
elapsed = end-start
fps = num_frames_processed/elapsed
print("FPS: {} , Elapsed Time: {} , Frames Processed: {}".format(fps, elapsed, num_frames_processed))
# closing all windows
cv2.destroyAllWindows()