树莓派3B+ opencv实时人脸检测(haar)ubuntu mate 18.04

1.硬件部分:

1.树莓派3B+。
2.树莓派原装csi接口摄像头。(也可使用usb摄像头)

2.环境搭建:

1.安装ubuntu mata 18.04 for 树莓派。
安装过程可参考此链接:树莓派ubuntu mate安装
另外附上ubuntumate官网:ubuntu mate官网
2.安装完成后还需要进行一些基础配置。
(1).使能csi摄像头。
sudo apt update

sudo apt upgrade

sudo apt-get install raspi-config

sudo raspi-config

用方向键和回车键选择控制
在这里插入图片描述
在这里插入图片描述
重启树莓派后:
sudo vim /etc/modules
打开文件在最后添加一行(这样才能将树莓派sci摄像头设置为video 0设备,以便opencv调用)
bcm2835-v4l2
在这里插入图片描述
完成后使用下方这句,如出现摄像头图像显示则恭喜你配置成功!
raspivid -o mykeychain.h264 -t 10000 -w 1280 -h 720

3.python3及pip,opencv的安装

1.安装python3.6:
参考以下链接:python3.6安装
2.安装pip3环境:
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
3.安装opencv
参考的是以下链接安装opencv:opencv pip安装

全部安装完成后进行测试:
python3
import cv2
在这里插入图片描述
如果不报错说明安装完成!

4.python代码实现

1.首先写两个函数,分别实现人脸识别和画框标记功能。

def get_faces(img):#人脸识别函数,传入读取到的图片
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#灰度化处理
    faces=face_cascade.detectMultiScale(gray,
    scaleFactor=1.5,#此值越小,检测出来的可疑目标越多
    minNeighbors=4,
    minSize=(20,20))#最小检测目标像素大小

    return faces,img,gray 

def draw_frame(faces,img,gray):
    for (x,y,w,h) in faces:#遍历faces列表中的元素
        cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)#画框框
    cv2.imshow("video",img)#图像显示

以上两段代码为基础检测与标记处理。
然而由于树莓派运算能力的问题,如果不采用特殊处理,画面帧率只有几帧,远不能满足我们的要求。所以需采用多线程及跳帧处理的方法来提高帧率。
以下代码为多线程及跳帧实现:

pool = mp.Pool( processes=2 )#创建多线程,线程数为2(也可以使用4线程)

read, img = camera.read()#从摄像头读取一帧图像
pr1 = pool.apply_async( get_faces, [ img ] )#将这帧图像提交给线程1
read, img = camera.read()#从摄像头读取一帧图像
pr2 = pool.apply_async( get_faces, [ img ] )#将这帧图像提交给线程2
#read, img = camera.read()
#pr3 = pool.apply_async( get_faces, [ img ] )
#read, img = camera.read()
#pr4 = pool.apply_async( get_faces, [ img ] )

fcount=1 #线程控制变量
jump=1 #跳帧控制变量
while True:#进入循环
    read,img=camera.read()
    if jump%2==0: #当是偶数帧的时候才去处理
        if  fcount == 1: #线程1工作
            pr1 = pool.apply_async( get_faces, [ img ] ) #将这帧图像提交给线程1
            faces, img, gray=pr2.get() #获取线程2的结果
            draw_frame( faces, img, gray ) #标记框位置

        elif fcount == 2: #线程2工作
            pr2 = pool.apply_async( get_faces, [ img ] )  #将这帧图像提交给线程2
            faces, img, gray=pr1.get()#获取线程1的结果
            draw_frame( faces, img, gray )#标记框位置
            fcount=0

        #elif fcount == 3:
        #    pr3 = pool.apply_async( get_faces, [ img ] )
        #    faces, img, gray=pr4.get()
        #    draw_frame( faces, img, gray )

        #elif fcount == 4:
        #    pr4 = pool.apply_async( get_faces, [ img ] )
        #   faces, img, gray=pr1.get()
        #   draw_frame( faces, img, gray )
        #   fcount = 0

        fcount += 1
    jump=jump+1
    if jump>29:
        jump=0
    c=cv2.waitKey(1)  
    if c==27: #按下键盘Esc键退出
        cv2.destroyAllWindows()
        break

完整代码如下:

import cv2
import multiprocessing as mp
import os
import time
face_cascade=cv2.CascadeClassifier('/home/yhk/cvfile/people.xml')
def get_faces(img):
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    faces=face_cascade.detectMultiScale(gray,
    scaleFactor=1.5,
    minNeighbors=4,
    minSize=(20,20))

    return faces,img,gray 

def draw_frame(faces,img,gray):
    for (x,y,w,h) in faces:
        cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
    cv2.imshow("video",img)
################################程序开始#######
camera= cv2.VideoCapture(0)
#camera.set(3,480)
#camera.set(4,320)
pool = mp.Pool( processes=2 )

read, img = camera.read()
pr1 = pool.apply_async( get_faces, [ img ] )
read, img = camera.read()
pr2 = pool.apply_async( get_faces, [ img ] )
#read, img = camera.read()
#pr3 = pool.apply_async( get_faces, [ img ] )
#read, img = camera.read()
#pr4 = pool.apply_async( get_faces, [ img ] )

fcount=1
jump=1
while True:
    read,img=camera.read()
    if jump%2==0:
        if  fcount == 1:
            pr1 = pool.apply_async( get_faces, [ img ] )
            faces, img, gray=pr2.get()
            draw_frame( faces, img, gray )

        elif fcount == 2:
            pr2 = pool.apply_async( get_faces, [ img ] )
            faces, img, gray=pr1.get()
            draw_frame( faces, img, gray )
            fcount=0

        #elif fcount == 3:
        #    pr3 = pool.apply_async( get_faces, [ img ] )
        #    faces, img, gray=pr4.get()
        #    draw_frame( faces, img, gray )

        #elif fcount == 4:
        #    pr4 = pool.apply_async( get_faces, [ img ] )
        #   faces, img, gray=pr1.get()
        #   draw_frame( faces, img, gray )
        #   fcount = 0

        fcount += 1
    jump=jump+1
    if jump>29:
        jump=0
    c=cv2.waitKey(1)
    if c==27:
        cv2.destroyAllWindows()
        break
    

最终效果:识别较为准确,帧率尚可。基本满足要求。
期间参考了很多博主大牛,希望分享出来帮助大家!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值