前言

用多线程处理视频并用于目标检测能够加快处理的帧率,而Python的threading模块封装了相关的操作,通过编写功能类继承threading.Thread即可实现自己的逻辑:通过调用start()方法,线程实例开始在单独的线程上下文中运行自己的run()函数处理任务,直到线程退出。在此期间,主线程可以继续执行任务。当主线程任务执行结束时,主线程可通过设置全局状态变量告知子线程退出,同时调用join()方法等待子线程运行结束。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import numpy as np
import cv2
import threading
from copy import deepcopy

thread_lock = threading.Lock()
thread_exit = False

class myThread(threading.Thread):
def __init__(self, camera_id, img_height, img_width):
super(myThread, self).__init__()
self.camera_id = camera_id
self.img_height = img_height
self.img_width = img_width
self.frame = np.zeros((img_height, img_width, 3), dtype=np.uint8)

def get_frame(self):
return deepcopy(self.frame)

def run(self):
global thread_exit
cap = cv2.VideoCapture(self.camera_id)
while not thread_exit:
ret, frame = cap.read()
if ret:
frame = cv2.resize(frame, (self.img_width, self.img_height))
thread_lock.acquire()
self.frame = frame
thread_lock.release()
else:
thread_exit = True
cap.release()

def main():
global thread_exit
camera_id = 0
img_height = 480
img_width = 640
thread = myThread(camera_id, img_height, img_width)
thread.start()

while not thread_exit:
thread_lock.acquire()
frame = thread.get_frame()
thread_lock.release()

cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
thread_exit = True
thread.join()

if __name__ == "__main__":
main()

上述代码使用多线程并行处理任务,为确保资源访问不受冲突,使用threading.Lock进行保护;主线程使用thread_exit全局状态变量控制着两个线程的运行状态,使得两个线程都拥有终止运行流程的话语权。