在python中使用带有多线程的opencv2时,CPU使用率非常高



我正在尝试使用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%。

两个问题

  1. th2在一个几乎紧密的循环中运行。它不会占用整个核心的CPU,因为waitKey(1)休眠了一段时间。

  2. 线程之间根本没有同步,但您需要它。你需要一个threading.Event来通知消费者线程一个新的帧。消费者线程必须等待,直到有新的帧可用,因为一次又一次地显示相同的旧帧是没有意义的。你可以偷懒,用waitKey(30)代替。对于显示线程来说,这已经足够好了。

  3. VideoCapture。你根本不做任何错误检查!你必须检查:

cap = cv2.VideoCapture("rtsp://test:Test12345@125.0.0.1")
assert cap.isOpened()
...

while True:
ret, frame = cap.read()
if not ret:
break
...

代码正常运行

  1. 第一个循环(线程)将尝试尽可能快地读取帧。帧可以每秒更新100次或更多,但速度太快了。尝试添加time.sleep(0.03).

  2. 在第二个循环中,您可以将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