需要硬件
- 树莓派一个
- 树莓派CSI摄像头 5MP Camera Board Module
## 固件安装 1. 树莓派,内存卡,电源安装好。 2. 将CSI摄像头按照步骤安装于树莓派上 图片来源
软件安装
树莓派系统安装
树莓派安装官网最新操作系统,推荐使用NOOBS,这是一个Raspbian的傻瓜安装版。
从官网下载NOOBS,解压zip文件
准备格式化后的SD卡,最好8G以上,从SD Formatter 官网下载SD Formatter,按照提示正常安装,将SD卡连接到PC上 通过(读卡器,电脑卡槽都行),格式化
把解压后的文件全部放入SD卡内,之后将SD卡安全拔出,把SD卡插入到Raspberry
连上键盘,鼠标,显示器,启动Rasberry,点击install 等待自动安装的完成。完成后 登录图形界面 (默认登录用户名为pi 密码为raspberry)
并通过以下命令完成系统更新 ' sudo apt-get update sudo apt-get -upgrade ' ### 在树莓派上启动摄像头模块 #### 开启摄像头 1. 确认系统更新完成后,用树莓派配置工具来激活摄像头模块 ' sudo raspi-config' 选择interfacing options 将Camera功能设置为Enable,之后操作系统自动重启
摄像头测试
重启之后,我们需要对摄像头是否工作做一个测试 'raspistill -t 2000 -o test.jpg' raspistill 是树莓派控制摄像头拍摄的命令, -t 为捕获图片等待时间 单位ms, -0为输出为文件 。
查看图片命令 'gpicview test.jpg' 若输出正常,则可以使用opencv来实现人脸识别
人脸识别框架
可以看出分为三个部分 - 数据收集 - 训练分类器 - 人脸识别 ### 主要参考文章
安装OpenCV
树莓派系统内自带Python,我们的人脸识别是基于OpenCV实现的,OpenCV具备很强的计算效率,而且可以应用于实时应用,非常适合于使用摄像头的实时人脸识别。 1. 通过以下代码安装OpenCV。 1
2
3sudo apt-get update
sudo apt-get upgrade
sudo apt-get install python-opencv1
2
3
4
sudo apt-get install python-pip
sudo apt-get install python-dev
sudo pip install picamera
人脸识别
从框架图中可知,实现人脸识别的基础任务是人脸检测,必须先捕捉到人脸才可以识别他。
最常见的人脸检测方法为使用Haar级联分类器 ,很幸运的是 OpenCV具备训练器和检测器。并且OpenCV也包含很多预训练的分类器,相关的xml可以从OpenCV上下载,或者从我的百度云盘里下载。
使用OpenCV创建人脸检测器
import
在python里使用摄像头
1 | from picamera import PiCamera |
1 | camera = PiCamera() |
载入cascade file文件来检测人脸
1 | face_cascade = cv2.CascadeClassifier('Cascades/haarcascade_frontalface_default.xml') |
haarcascade_frontalface_default.xml 为OpenCV预训练的分类器,路径按照自己放置的路径填写。
定义一些主要函数
- get_faces 函数
1 | ''' |
- draw_frame 函数 在识别的脸部画上识别框
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20'''
Args:
img: 视频拍摄中的图像
faces:识别出的脸
Return:
None
'''
def draw_frame(img,faces):
global fps
global time_t
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y), (x+w,y+h),(100,255,100),2)
cv2.putText(img, "face ", (x,y),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255),2)
####show fps
fps = fps +1
sfps = fps/(time.time()-t_start)
cv2.putText(img, "FPS"+str(int(sfps)), (10,10), cv2.FONT_HERSHEY_SIMPLEX, 0.5,(0,0,255),2)
#######show image
cv2.imshow("frame", img)
cv2.waitKey(1) - 为了提高拍摄视频的帧数使用functools函数 ## 源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def main():
pool = mp.Pool(processes=4)
fcount = 0
camera.capture(rawCapture, format="bgr")
r1 = pool.apply_async(get_faces, [rawCapture.array])
r2 = pool.apply_async(get_faces, [rawCapture.array])
r3 = pool.apply_async(get_faces, [rawCapture.array])
r4 = pool.apply_async(get_faces, [rawCapture.array])
face1, img1 = r1.get()
face2, img2 = r2.get()
face3, img3 = r3.get()
face4, img4 = r4.get()
rawCapture.truncate(0)
for frame in camera.capture_continuous(rawCapture, format="bgr",use_video_port=True):
image = frame.array
if fcount == 1:
r1 = pool.apply_async(get_faces, [image])
face2, img2 = r2.get()
draw_frame(img2, face2)
if fcount == 2:
r2 = pool.apply_async(get_faces, [image])
face3, img3 = r3.get()
draw_frame(img3, face3)
if fcount == 3:
r3 = pool.apply_async(get_faces, [image])
face4, img4 = r4.get()
draw_frame(img4, face4)
if fcount == 4:
r4 = pool.apply_async(get_faces, [image])
face1, img1 = r1.get()
draw_frame(img1, face1)
fcount = 0 # restart the count loop
fcount += 1
rawCapture.truncate(0)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
'''
A camera script
'''
###############import##########
from picamera.array import PiRGBArray
import numpy as np
import cv2
import time
import os
from picamera import PiCamera
from functools import partial
import multiprocessing as mp
#################import###########
resx = 320
resy = 240
#########setup camera
camera = PiCamera()
camera.resolution = (320,240)
camera.framerate = 60
rawCapture =PiRGBArray(camera, size=(320,240))
face_cascade = cv2.CascadeClassifier('Cascades/haarcascade_frontalface_default.xml')
t_start = time.time()
fps = 0
#####main function##########
def get_faces(img):
image = img
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
faces =face_cascade.detectMultiScale(gray)
return faces,image
def draw_frame(img,faces):
global fps
global time_t
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y), (x+w,y+h),(100,255,100),2)
cv2.putText(img, "face ", (x,y),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255),2)
####show fps
fps = fps +1
sfps = fps/(time.time()-t_start)
cv2.putText(img, "FPS"+str(int(sfps)), (10,10), cv2.FONT_HERSHEY_SIMPLEX, 0.5,(0,0,255),2)
#######show image
cv2.imshow("frame", img)
cv2.waitKey(1)
def main():
pool = mp.Pool(processes=4)
fcount = 0
camera.capture(rawCapture, format="bgr")
r1 = pool.apply_async(get_faces, [rawCapture.array])
r2 = pool.apply_async(get_faces, [rawCapture.array])
r3 = pool.apply_async(get_faces, [rawCapture.array])
r4 = pool.apply_async(get_faces, [rawCapture.array])
face1, img1 = r1.get()
face2, img2 = r2.get()
face3, img3 = r3.get()
face4, img4 = r4.get()
rawCapture.truncate(0)
for frame in camera.capture_continuous(rawCapture, format="bgr",use_video_port=True):
image = frame.array
if fcount == 1:
r1 = pool.apply_async(get_faces, [image])
face2, img2 = r2.get()
draw_frame(img2, face2)
if fcount == 2:
r2 = pool.apply_async(get_faces, [image])
face3, img3 = r3.get()
draw_frame(img3, face3)
if fcount == 3:
r3 = pool.apply_async(get_faces, [image])
face4, img4 = r4.get()
draw_frame(img4, face4)
if fcount == 4:
r4 = pool.apply_async(get_faces, [image])
face1, img1 = r1.get()
draw_frame(img1, face1)
fcount = 0 # restart the count loop
fcount += 1
rawCapture.truncate(0)
if __name__ == '__main__':
main()