我正在尝试使用opencv2创建自动考勤系统,其中我需要从IP摄像机获得rtsp流,从中找到人脸并识别人脸。
我创建了不同的线程从帧捕获和绘图,因为人脸识别功能需要一些时间来识别人脸。
但是仅仅创建2个线程,一个用于读取帧,另一个用于绘制,使用了大约70%的CPU。创建pytorch_facenet模型会增加80-90%的CPU使用率。
有没有人知道如何减少CPU的使用?
我的程序:
import cv2
import threading
from facenet_pytorch import InceptionResnetV1
cap = cv2.VideoCapture("rtsp://test:Test12345@125.0.0.1")
resnet = InceptionResnetV1(pretrained='vggface2').eval()
ret, frame = cap.read()
exit = False
def th1():
global ret, frame, exit
while True:
ret, frame = cap.read()
if exit:
break
def th2():
global ret, frame, exit
while True:
cv2.imshow('frame', frame)
cv2.waitKey(1)
if cv2.getWindowProperty('frame',cv2.WND_PROP_VISIBLE) < 1:
exit = True
break
t1 = threading.Thread(target=th1)
t1.start()
t2 = threading.Thread(target=th2)
t2.start()
:
我使用time.sleep(0.2)在我的所有线程除了帧读取。它工作了,我的CPU使用率现在是30%。
两个问题
-
th2
在一个几乎紧密的循环中运行。它不会占用整个核心的CPU,因为waitKey(1)
休眠了一段时间。 -
线程之间根本没有同步,但您需要它。你需要一个
threading.Event
来通知消费者线程一个新的帧。消费者线程必须等待,直到有新的帧可用,因为一次又一次地显示相同的旧帧是没有意义的。你可以偷懒,用waitKey(30)
代替。对于显示线程来说,这已经足够好了。 -
VideoCapture
。你根本不做任何错误检查!你必须检查:
cap = cv2.VideoCapture("rtsp://test:Test12345@125.0.0.1")
assert cap.isOpened()
...
和
while True:
ret, frame = cap.read()
if not ret:
break
...
代码正常运行
-
第一个循环(线程)将尝试尽可能快地读取帧。帧可以每秒更新100次或更多,但速度太快了。尝试添加
time.sleep(0.03)
. -
在第二个循环中,您可以将
waitKey()
参数更改为30。import time def th1(): global ret, frame, exit while True: ret, frame = cap.read() time.sleep(0.03) if exit: break def th2(): global ret, frame, exit while True: cv2.imshow('frame', frame) cv2.waitKey(30) if cv2.getWindowProperty('frame',cv2.WND_PROP_VISIBLE) < 1: exit = True break