Ganxas' 2024-05-10 22:38 采纳率: 0%
浏览 50

yolo dlib 处理本地视频卡顿问题

第一次用csdn,想问一下(如果格式之类的有错,我在这里提前说声抱歉)
我这里用了https://blog.csdn.net/qq_46554815/article/details/122778429 里的办法把yolov5的detect做成api在别的文件里调用,和dlib一起用来检测结果。
但是现在检测摄像头比较正常,检测本地文件就特别卡,整个视频特别慢
请问能看出原因吗?我的配置是R5 5600H+RTX3050 laptop,一运行就是cpu95%,内存88%。
然后有什么解决办法吗?

因为是python初学者,所以下面的代码肯定有挺多问题的,如果是单纯带不动的话,那有哪里能优化的吗?
环境是python3.9,torch1.9.1+cu111,cuda11.1,cudnn8005,因为yolo那边的关系这几个的版本很难改。

提前表示感谢。


from scipy.spatial import distance as dist
from imutils import face_utils
import numpy as np
import imutils
import dlib
import cv2
import detect


# 初始化人脸检测器
a = detect.detectapi(weights='weights/best.pt')

# 定义全局变量
global NUMtotal


def write_list_to_js(file_path, variable_name, data):
    with open(file_path, 'w') as js_file:
        js_file.write(f"const {variable_name} = {data};\n")


# 定义函数:计算眼睛长宽比
def eye_aspect_ratio(eye):
    A = dist.euclidean(eye[1], eye[5])
    B = dist.euclidean(eye[2], eye[4])
    C = dist.euclidean(eye[0], eye[3])
    ear = (A + B) / (2.0 * C)
    return ear


# 定义函数:计算嘴巴长宽比
def mouth_aspect_ratio(mouth):
    A = np.linalg.norm(mouth[2] - mouth[9])
    B = np.linalg.norm(mouth[4] - mouth[7])
    C = np.linalg.norm(mouth[0] - mouth[6])
    mar = (A + B) / (2.0 * C)
    return mar


# 定义函数:处理摄像头读取和数据处理

def process_camera(Address):
    global NUMtotal
    conf_Ts, conf_Tp, conf_Td, ts, tp, td, tus, tud, tup = 0, 0, 0, 0, 0, 0, 0, 0, 0
    N_s, N_p, N_d, TOTAL, mTOTAL, PERCLOS, Tired = 0, 0, 0, 0, 0, 0, False
    EYE_AR_THRESH, EYE_AR_CONSEC_FRAMES, MAR_THRESH, MOUTH_AR_CONSEC_FRAMES = 0.15, 3, 0.5, 3
    COUNTER, TOTAL, mCOUNTER, mTOTAL, pernum, PERCLOS = 0, 0, 0, 0, 0, 0
    per = [0] * 30

    detector = dlib.get_frontal_face_detector()
    predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
    (lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
    (rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
    (mStart, mEnd) = face_utils.FACIAL_LANDMARKS_IDXS["mouth"]
    cap = cv2.VideoCapture(Address)

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

        frame = imutils.resize(frame, width=720)
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        rects = detector(gray, 0)
        result, names = a.detect([frame])
        frame = result[0][0]
        t = dict(enumerate(result))
        confi_total = result[0][1:3]
        confi_total = confi_total[0]
        confi_total = np.asarray(confi_total)
        if len(confi_total) == 0:
            conf = [0, 0, 0, 0]
        elif len(confi_total) == 1:
            conf = np.array([confi_total[0, 0], 0, 0, 0])
        elif len(confi_total) == 2:
            conf = np.array(confi_total[0:2, 0])
        elif len(confi_total) == 3:
            conf = np.array(confi_total[0:3, 0])
        elif len(confi_total) == 4:
            conf = np.array(confi_total[0:4])

        conf_As = np.any(conf == 1)
        conf_Ap = np.any(conf == 2)
        conf_Ad = np.any(conf == 3)

        if conf_As:
            if conf_Ts == 0 and ts < 5:
                ts += 1
            elif conf_Ts == 0 and ts == 5:
                N_s += 1
                conf_Ts = 1
                ts = 0
            elif tus > 0:
                tus = 0
        if not conf_As:
            if conf_Ts == 1 and tus < 7:
                tus += 1
            elif conf_Ts == 1 and tus == 7:
                conf_Ts = 0
                tus = 0
            elif ts > 0:
                ts = 0

        if conf_Ap:
            if conf_Tp == 0 and tp < 5:
                tp += 1
            elif conf_Tp == 0 and tp == 5:
                conf_Tp = 1
                N_p += 1
                tp = 0
            elif tup > 0:
                tup = 0
        if not conf_Ap:
            if conf_Tp == 1 and tup < 7:
                tup += 1
            elif conf_Tp == 1 and tup == 7:
                conf_Tp = 0
                tup = 0
            elif tp > 0:
                tp = 0

        if conf_Ad:
            if conf_Td == 0 and td < 5:
                td += 1
            elif conf_Td == 0 and td == 5:
                N_d += 1
                conf_Td = 1
                td = 0
            elif tud > 0:
                tud = 0
        if not conf_Ad:
            if conf_Td == 1 and tud < 7:
                tud += 1
            elif conf_Td == 1 and tud == 7:
                conf_Td = 0
                tud = 0
            elif td > 0:
                td = 0

        for rect in rects:
            shape = predictor(gray, rect)
            shape = face_utils.shape_to_np(shape)
            leftEye = shape[lStart:lEnd]
            rightEye = shape[rStart:rEnd]
            mouth = shape[mStart:mEnd]
            leftEAR = eye_aspect_ratio(leftEye)
            rightEAR = eye_aspect_ratio(rightEye)
            ear = (leftEAR + rightEAR) / 2.0
            mar = mouth_aspect_ratio(mouth)

            if ear < EYE_AR_THRESH:
                COUNTER += 1
            else:
                if COUNTER >= EYE_AR_CONSEC_FRAMES:
                    TOTAL += 1
                COUNTER = 0

            if pernum < 30:
                if ear < EYE_AR_THRESH:
                    per[pernum] = 1
                else:
                    per[pernum] = 0
                pernum = pernum + 1
            else:
                pernum = 0
            PERCLOS = sum(per) / 30

            if mar > MAR_THRESH:
                mCOUNTER += 1
            else:
                if mCOUNTER >= MOUTH_AR_CONSEC_FRAMES:
                    mTOTAL += 1
                mCOUNTER = 0

        if TOTAL >= 10 or mTOTAL >= 5 or PERCLOS > 0.12:
            Tired = 1
        else:
            Tired = 0
        cv2.imshow("Frame", frame)

        NUMtotal = [N_s, N_p, N_d, TOTAL, mTOTAL, PERCLOS, Tired]

        if cv2.waitKey(1) & 0xFF == 27:
            cap.release()
            cv2.destroyAllWindows()
            break


process_camera('test.mp4')

  • 写回答

2条回答 默认 最新

  • 笑面虎 2024-05-10 22:38
    关注

    以下内容由CHATGPT及笑面虎共同生成、有用望采纳:


    【您想要解决的问题】: 您提问的目的是解决在使用YOLOv5和dlib库处理本地视频时出现的卡顿问题。您的电脑配置是R5 5600H+RTX3050,但在运行时CPU和内存使用率都非常高,导致视频播放缓慢。

    【问题出现原因】:

    1. CPU和内存使用率高:您的代码可能在处理视频时没有进行优化,导致资源占用过高。
    2. 视频处理瓶颈:视频解码、人脸检测、对象检测等操作可能在CPU上执行,而不是更高效的GPU。
    3. 循环内操作:在while循环内进行了大量的计算和处理,没有进行必要的优化。

    【问题解决方案】:

    1. 优化资源使用:减少循环内的计算量,避免不必要的重复计算。
    2. 使用GPU加速:如果可能,尝试使用支持GPU加速的库,例如将OpenCV的某些操作转移到GPU上。
    3. 多线程或异步处理:考虑使用多线程或异步编程技术来分散计算负载。
    4. 降低视频分辨率:在处理视频时降低分辨率可以减少计算量。
    5. 代码优化:优化代码逻辑,例如使用更高效的算法或数据结构。

    【提供代码】: 由于代码优化可能涉及多个方面,这里提供一个简化的示例,用于降低视频处理的负载:

    # 其他库和函数保持不变
    
    def process_camera(Address):
        # ... 省略部分代码 ...
    
        cap = cv2.VideoCapture(Address)
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 720)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)  # 降低视频分辨率
    
        while True:
            ret, frame = cap.read()
            if not ret:
                break
    
            # ... 省略部分代码 ...
    
            cv2.imshow("Frame", frame)
            if cv2.waitKey(1) & 0xFF == 27:
                break
    
        cap.release()
        cv2.destroyAllWindows()
    
    # 调用函数
    process_camera('test.mp4')
    

    【代码运行方式】:

    1. 确保您的系统已经安装了Python 3.9,以及所需的库(torch, opencv, dlib等)。
    2. 将上述代码保存为.py文件。
    3. 在命令行或IDE中运行该Python脚本。

    【代码预期运行结果】: 预期中,降低视频分辨率和优化循环内操作将减少CPU和内存的使用率,从而减少视频播放时的卡顿。

    【推荐相关链接】:

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 5月10日