树莓派3B+指南(九)解决帧率不足的问题

解决帧率不足的问题

这个可能是我目前遇到最大的问题了,如果帧率很低,是没有办法满足人脸识别跟踪的。希望下面的方法可以有效解决这个问题。

查看网上资料,使用多进程,多核处理会快一些。

搞了好几天,终于搞出点眉目,但是因为树莓派的内存实在有限,如果逐帧处理,尽管用上了所有cpu资源,还是会很卡。所以有了以下的版本,可选择跳帧,可以选择逐帧。可以根据自己的需求更改。

import multiprocessing as mp
import cv2
import dlib

def detect_face(frame,value):
    img = frame
    dets = detector(img, 1)
    for index, face in enumerate(dets):
 
        left = face.left()
        top = face.top()
        right = face.right()
        bottom = face.bottom()

#因为如果没有检测到脸,上面四个变量是不存在的,
#会报出UnboundLocalError的错误,所以要处理一下。           
    try:
        value[:] = [left,top,right,bottom]
    except UnboundLocalError:
        value[:] = [0,0,0,0]

def draw_line(img,box):
    
    left = box[0]
    top = box[1]
    right = box[2]
    bottom = box[3]
    
#给传进来的img画框,并返回
    cv2.rectangle(img, (left*2, top*2), (right*2, bottom*2), (255, 0, 0), 1)
    return img
    
if __name__=='__main__':

#initial detector and cap
#树莓派的运行内存有限,所以要将采集的图片像素缩小一些,便于计算。
    detector = dlib.get_frontal_face_detector() #获取人脸分类器for face detection
    cap = cv2.VideoCapture(-1)  #Turn on the camera
    cap.set(3,320)
    cap.set(4,240)

#initial boxes
#初始化框脸的初始位置
    box1 = mp.Array('i',[0,0,0,0])
    box2 = mp.Array('i',[0,0,0,0])
    
#initial Windowbox
    cv2.namedWindow('success', cv2.WINDOW_AUTOSIZE)
    
#initial frames and processes
#想要几个进程处理图片就用几组,但并不是用的越多越好,
#树莓派的CPU一共有4个核,全部用上可能会影响其他的性能,自己试的时候2个会好一点。
    ret, frame11 = cap.read()
    img11 = cv2.resize(frame11,(160,120))
    res1 = mp.Process(target=detect_face,args=(img11,box1))
    res1.start()

#可以把识别用的图片像素缩小,可以加快速度,同时也可以减少cpu负担,
#然后再把识别框扩大相应倍数,在原图片上放出。
    ret, frame21 = cap.read()
    img21 = cv2.resize(frame21,(160,120))
    res2 = mp.Process(target=detect_face,args=(img21,box2))
    res2.start()
    
    while(cap.isOpened()):
#process 1
 #如果想要逐帧处理,那就用pass,如果想跳帧就选择上面两句
        if (res1.is_alive()):
            ret, frame12 = cap.read()
            cv2.imshow('success',draw_line(frame12,box1))            
#            pass           
        else:
            ret, frame11 = cap.read()
            cv2.imshow('success',draw_line(frame11,box1))
          	img11 = cv2.resize(frame11,(160,120))           
            res1 = mp.Process(target=detect_face,args=(img11,box1))
            res1.start()
            
#process 2
        if (res2.is_alive()):
            ret, frame22 = cap.read()
            cv2.imshow('success',draw_line(frame22,box2))  
#            pass          
        else:
            ret, frame21 = cap.read()
            cv2.imshow('success',draw_line(frame21,box2))
          	img21 = cv2.resize(frame21,(160,120)) 
            res2 = mp.Process(target=detect_face,args=(img21,box2))
            res2.start()

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
            
    cv2.destroyAllWindows()
    cap.release()
    print('END')

在这几天调适的过程中,也遇到了很多问题,做一下总结:
1.多进程不可以对cv2.imshow()同时操作,会因为抢占窗口资源而报错
2.多进程不可以对cv2.imread()同时操作,会因为抢占摄像头资源而报错
3.process不能有返回值,Queue只能返回数,apply_async()不能确定进程状态
4.Process确定进程状态用.is_alive()来确定
5.apply_async()用.get()来获得返回值,不可以没有返回值。
6.Pipe()的接收端如果没有接收到东西,会一直挂起,阻塞进程。
差不过就是这些,想起来之后再补充吧。

至此就结束了,希望可以帮助到大家!

猜你喜欢

转载自blog.csdn.net/weixin_44086593/article/details/87541473
今日推荐