赞
踩
本人目前用树莓派4B仅了解到了人脸检测/人脸识别的四种方法:
人脸识别对于大家来说应该都是挺耳熟的,它就是从人脸检测升级而来的。可能就会有人问:这人脸识别和人脸检测有啥不一样咧?
人脸检测是人脸识别的基础,人脸检测是检测到这一图片或这一画面中有人脸,但不知道这是谁的脸;人脸识别便是先给人脸打上了“标签”,告诉电脑某某某1的人脸长这样,每次检测到人脸就拿来与打了“标签”的人脸作对比,相似率达到多少多少(自己设定的值,如80%)时,就认为这张人脸叫某某某1,若达不到,就“不认识”。
OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
OpenCV用C++语言编写,它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS,OpenCV主要倾向于实时视觉应用,并在可用时利用MMX和SSE指令, 如今也提供对于C#、Ch、Ruby,GO的支持。
有许多大佬已经写过如何安装OpenCV了,本人也就不再“重复造轮子”了。
大概提一下安装步骤吧:
(再另提一下,全程大概出现三个或四个错误,还请做好心理准备,毕竟本人当时也编译了两三天、掉进了好几个坑才编译好的,当然了是因为需要重新编译所以才花那么久的)
安装:
OpenCV的参考安装文章1
OpenCV的参考安装文章2(子豪兄的文章)
安装OpenCV3.4.0版本在编译过程中出现问题的解决方法:
参考解决方法一
参考解决方法二
当初本人便是结合这两种解决办法才能成功编译的,安装OpenCV的确是挺麻烦,所以需要不断尝试解决那些出现的错误,一般的出错时都会有所提示是在哪个文件夹、哪行代码、哪个文件出了问题,是缺失某个文件还是文件地址错误,都会有所提示,再不懂就仔细揣摩那两个参考解决方法或多百度百度吧。
安装OpenCV成功后,在opencv-3.4.0/data中会有好几个文件,其中以下文件存放了OpenCV自带的级联分类器文件,都是已经训练好的文件,可以检测人脸、眼睛、嘴等部位,但效果也并非就是完美的,会存在一些准确率问题,毕竟是开源的嘛,想要准确率很高的还是得自己训练。
这四个文件夹分别是四种检测方法,检测方法的不同自然准确率什么的也会存在差异(这是本人的猜测)。如下图所示为检测各种部位的分类器:
以下为使用OpenCV对图片里的人进行人脸检测的代码:
import cv2 #选择此代码目录下的某个图片文件 img = cv2.imread('image2.jpg',1) # 导入人脸级联分类器,'.xml'文件里包含训练出来的人脸特征 face_engine = cv2.CascadeClassifier('/home/pi/Downloads/opencv-3.4.0/data/haarcascades/haarcascade_frontalface_default.xml') # 检测设置,将图片放大1.1倍(一般设1.1倍,看效果而定) # 重复检测的次数为5次(检测次数越多,速度越慢,检测也越严格,准确率可能有所提升) faces = face_engine.detectMultiScale(img,scaleFactor=1.1,minNeighbors=5) # 对图片进行人脸检测,之后得到人脸的坐标(一个矩形框),再用蓝色框框出,线宽为2 for (x,y,w,h) in faces: img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) # (255,0,0)=(B,G,R) # 显示图片 cv2.imshow('img',img) # 检测是否有按键按下 cv2.waitKey(0) # 关闭窗口,释放占用的资源 cv2.destroyAllWindows()
以下为OpenCV使用摄像头对人脸和眼睛进行动态检测的代码:
import cv2 # 导入人脸级联分类器,'.xml'文件里包含训练出来的人脸特征 face_engine = cv2.CascadeClassifier('/home/pi/Downloads/opencv-3.4.0/data/haarcascades/haarcascade_frontalface_default.xml') # 导入人眼级联分类器,'.xml'文件里包含训练出来的人眼特征 eye_cascade = cv2.CascadeClassifier('/home/pi/Downloads/opencv-3.4.0/data/haarcascades/haarcascade_eye.xml') # 调用摄像头摄像头 cap = cv2.VideoCapture(0) while(True): # 获取摄像头拍摄到的画面 # 会得到两个参数,一个为存放是否捕捉到图像(True/False),另一个为存放每帧的图像 ret, frame = cap.read() # 每帧图像放大1.1倍,重复检测10次 faces = face_engine.detectMultiScale(frame,1.1, 10) img = frame for (x,y,w,h) in faces: # 画出人脸框,蓝色,画笔宽度为2 img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2) # 框选出人脸区域,在人脸区域而不是全图中进行人眼检测,节省计算资源 face_area = img[y:y+h, x:x+w] eyes = eye_cascade.detectMultiScale(face_area,1.1,5) # 用人眼级联分类器在人脸区域进行人眼识别,返回的eyes为眼睛坐标列表 for (ex,ey,ew,eh) in eyes: #画出人眼框,绿色,画笔宽度为1 cv2.rectangle(face_area,(ex,ey),(ex+ew,ey+eh),(0,255,0),1) # 实时展示效果画面 cv2.imshow('frame2',img) # 每5毫秒监听一次键盘动作 if cv2.waitKey(5) & 0xFF == ord('a'): #当按下“a”键时退出人脸检测 break # 最后,关闭所有窗口 cap.release() cv2.destroyAllWindows()
openmv功能也挺强大的,自身就可以实现各种检测,如颜色检测、物体检测、人脸检测、人脸识别等等,与树莓派也可以通讯,通讯方式可有WiFi、蓝牙、I2C等(具体如何实现本人还未开始研究)。
OpenMV是一个开源,低成本,功能强大的机器视觉模块。以STM32F427CPU为核心,集成了OV7725摄像头芯片,在小巧的硬件模块上,用C语言高效地实现了核心机器视觉算法,提供Python编程接口。使用者们(包括发明家、爱好者以及智能设备开发商)可以用Python语言使用OpenMV提供的机器视觉功能,为自己的产品和发明增加有特色的竞争力。
OpenMV上的机器视觉算法包括寻找色块、人脸检测、眼球跟踪、边缘检测、标志跟踪等。可以用来实现非法入侵检测、产品的残次品筛选、跟踪固定的标记物等。使用者仅需要写一些简单的Python代码,即可轻松的完成各种机器视觉相关的任务。小巧的设计,使得OpenMV可以用到很多创意的产品上。比如,可以给自己的机器人提供周边环境感知能力;给智能车增加视觉巡线功能;给智能玩具增加识别人脸功能,提高产品趣味性等;甚至,可以给工厂产品线增加残次品筛选功能等。
openmv的具体介绍1
openmv的具体介绍2(星瞳科技)
openmv内置了人脸检测的算法,是利用Haar算子来进行人脸的检测,可以快速的在视野中找到人脸,但获取图像后必须将图像转变成灰度图才可以进行计算(将图像转为灰度图可以提高其人脸检测的速度),然后做框出人脸位置等步骤。
代码如下:
(需要人脸与该模块摄像头在30cm左右的距离内才可以检测到人脸)
import sensor, time, image # 重置感光元件 sensor.reset() # 感光元件设置 sensor.set_contrast(3) sensor.set_gainceiling(16) # HQVGA和灰度对于人脸识别效果最好 sensor.set_framesize(sensor.HQVGA) sensor.set_pixformat(sensor.GRAYSCALE) #注意人脸识别只能用灰度图哦 sensor.set_vflip(True) # 设置画面垂直翻转 sensor.set_hmirror(True) # 设置画面左右翻转 # 加载Haar算子 # 默认情况下,这将使用所有阶段,更低的satges更快,但不太准确。 face_cascade = image.HaarCascade("frontalface", stages=25) #image.HaarCascade(path, stages=Auto)加载一个haar模型。haar模型是二进制文件, #这个模型如果是自定义的,则引号内为模型文件的路径;也可以使用内置的haar模型, #比如“frontalface” 人脸模型或者“eye”人眼模型。 #stages值未传入时使用默认的stages。stages值设置的小一些可以加速匹配,但会降低准确率。 print(face_cascade) # FPS clock clock = time.clock() while (True): clock.tick() # 拍摄一张照片 img = sensor.snapshot() # 找到对象 # 注意:低比例因子缩小图像更多,检测更小的对象 # 阈值越高,检出率越高,假阳性越多。 objects = img.find_features(face_cascade, threshold=1, scale=1.5) #image.find_features(cascade, threshold=0.5, scale=1.5),thresholds越大, #匹配速度越快,错误率也会上升。scale可以缩放被匹配特征的大小。 #在找到的目标上画框,标记出来 for r in objects: img.draw_rectangle(r) # 打印FPS。 # 注:实际FPS更高,流FB使它更慢。 print(clock.fps())
face_recognition库是最为简洁的人脸识别库,可以直接通过捕捉图片中128维的人脸向量进行存储,打上“标签”,假设为某某某2,再与其他图片/画面中捕获128维的人脸向量做对比,相似度达到一定值后便判定刚刚识别的是某某某2的人脸。
(128维的人脸向量:也就是会在人脸上获取128个点的向量之类的,好比如眉毛的轮廓、鼻子的轮廓、嘴的轮廓等许多个点组成的线)
face_recognition的视频教程(在播放到37分后为安装教程,50分后为使用教程 很抱歉哈,那位UP主的视频已下架(2023.05.23本人亲自前往确认的))
有两种方法(本人试的是第一种):
方法一
sudo apt --upgrade install cmake
再安装face_recognition
pip3 install face_recognition
sudo apt install cmake
再安装face_recognition
pip3 install face_recognition
方法二
- 加载已知图片和待识别图片
- 对图片中的人脸进行编码
- 建立人脸库
- 识别待识别图片中的人脸
- 标记姓名并展示
- 释放资源
详细一些的说明 / 步骤:
该代码是将检测速度提升了,其实其他提速的方法也挺(可能也许大概八成)简单的,可以用于参考:
1.替换人脸检测方法成OpenCV的Haar人脸检测方法;(好像是在输出位置的向量上需要转换,有些麻烦,原理上是可以的)
2.换成在灰度图上检测;(按道理可以,但本人还未成功,猜测是颜色格式没转换好的问题)
3.将画面大小按比例缩小再检测;
4.将按比例缩小后的画面作为显示的画面;
5.采用多个CPU一起检测(目前还没尝试成功,但据说可以);
6.使用神经棒加速;(猜测可以)
7. …(目前知识有限,待续)
以下代码仅采用了将画面大小按比例缩小的方法,速度提升了10s左右:
(这是指从程序开始到显示画面的时间减少了10s左右,实际上还是会花15s左右做预处理。检测到人脸后的延迟为3s左右,这也跟网络延迟有关)
import face_recognition import cv2 import numpy as np # 用opencv获取摄像头画面 video_capture = cv2.VideoCapture(0) # 获取obama图片,提取128维的人脸向量 obama_image = face_recognition.load_image_file("obama.jpg") obama_face_encoding = face_recognition.face_encodings(obama_image)[0] # 获取biden图片,提取128维的人脸向量 biden_image = face_recognition.load_image_file("biden.jpg") biden_face_encoding = face_recognition.face_encodings(biden_image)[0] # 存储128维的人脸向量 known_face_encodings = [ obama_face_encoding, biden_face_encoding ] # 存储人脸名字 known_face_names = [ "Barack Obama", "Joe Biden" ] # 初始化 face_locations = [] face_encodings = [] face_names = [] process_this_frame = True while True: ret, frame = video_capture.read() # 将画面缩小4倍 small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) # 将BGR颜色格式转换为RGB rgb_small_frame = small_frame[:, :, ::-1] if process_this_frame: face_locations = face_recognition.face_locations(rgb_small_frame) face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations) face_names = [] for face_encoding in face_encodings: matches = face_recognition.compare_faces(known_face_encodings, face_encoding) name = "Unknown" face_distances = face_recognition.face_distance(known_face_encodings, face_encoding) best_match_index = np.argmin(face_distances) if matches[best_match_index]: name = known_face_names[best_match_index] face_names.append(name) process_this_frame = not process_this_frame for (top, right, bottom, left), name in zip(face_locations, face_names): # 此处将前面缩小的比例还原(放大4倍),这样才可以在原图像上框对人脸 top *= 4 right *= 4 bottom *= 4 left *= 4 cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED) font = cv2.FONT_HERSHEY_DUPLEX cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1) # 此处是显示原图像,若将显示的图像换成缩小4倍后的图像,速度也能提升 cv2.imshow('Video', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break video_capture.release() cv2.destroyAllWindows()
利用百度智能云的人脸识别系统实现人脸识别也是很简单的,但是树莓派需要在联网的情况下才可以使用该人脸识别,除非部署了离线版的人脸识别系统。
1.首先需要在百度智能云上创建一个账号,或者使用百度账号登录;
2.进入后创建一个人脸识别应用;
3.下图框出的三个内容后面会用到,因此需要记下;
4.创建用户组和用户(用户组和用户的名称都只能是数字或英文,不能有中文)
5.给用户上传用户的正面照(上传不同的照片越多越好)
6.下载SDK
将SDK压缩包解压得到以下文件:
在树莓派4B上部署SDK:
1.先通过U盘或VNC的文件传输将SDK文件夹传输给树莓派
2. 安装pip(若已经安装了则跳过安装pip)和setuptools
2.1 安装setuptools
2.1.1 下载安装包(此安装包为2020.8.14更新的49.6.0版本)
wget https://files.pythonhosted.org/packages/38/cc/db23dbe4efc464c3c0111fedf7d46de8888f05b09488d610f6f8ab6e2544/setuptools-49.6.0.zip
2.1.2 解压
unzip setuptools-49.6.0.zip
2.1.3 安装
cd setuptools-49.6.0
sudo python setup.py build
sudo python setup.py install
2.2 安装pip(若已经安装了的就跳过)
方法一:
sudo apt-get install -y python-pip
方法二:
2.2.1 下载(此安装包为2020.8.11更新的20.2.2版本)
wget https://files.pythonhosted.org/packages/73/8e/7774190ac616c69194688ffce7c1b2a097749792fea42e390e7ddfdef8bc/pip-20.2.2.tar.gz
2.2.2 解压(注意版本是否一致)
tar zxvf pip-20.2.2.tar.gz
2.2.3 安装(安装前请看清楚下载好的文件夹名是否一致,随着更新,版本会不一样)
cd ../pip-20.2.2/
sudo python3 setup.py install
3. 安装SDK
假设传输过来的SDK文件放在了Download文件夹内,则先进入该文件夹内:
cd Downloads/aip-python-sdk-2.2.15
然后再安装:
sudo pip install baidu-aip
得到类似如下图所示画面就说明SDK已经安装成功:
接下来还需安装API:
sudo python3 setup.py install
这样就可以调用百度智能云的人脸识别了
当使用以下代码后,会生成一个名为“ming_dan”的文本在当前文件夹内,用于记录检测人的姓名和时间。
from aip import AipFace from picamera import PiCamera import urllib.request import RPi.GPIO as GPIO import base64 import time import datetime #百度人脸识别API账号信息 APP_ID = '19127770' API_KEY = 'bgaoZtrDyFm097RZy4zc1b1p' SECRET_KEY = '8dPNLaUyG7HKBDHU848y6gS7lZHvfQU3' client = AipFace(APP_ID, API_KEY, SECRET_KEY)#创建一个客户端用以访问百度云 #图像编码方式 IMAGE_TYPE='BASE64' camera = PiCamera()#定义一个摄像头对象 #用户组 GROUP = 'one' #照相函数 def getimage(): camera.resolution = (1024,768)#摄像界面为1024*768 camera.start_preview()#开始摄像 time.sleep(1) camera.capture('faceimage.jpg')#拍照并保存 time.sleep(1) #对图片的格式进行转换 def transimage(): f = open('faceimage.jpg','rb') img = base64.b64encode(f.read()) return img #上传到百度api进行人脸检测 def go_api(image): result = client.search(str(image, 'utf-8'), IMAGE_TYPE, GROUP);#在百度云人脸库中寻找有没有匹配的人脸 if result['error_msg'] == 'SUCCESS':#如果成功了 name = result['result']['user_list'][0]['user_id']#获取名字 score = result['result']['user_list'][0]['score']#获取相似度 if score > 80:#如果相似度大于80 if name == 'qin_guan_lin': # 此为自己设置的用户组中的用户名(只能是由字母和数字组成) name1 = '小霖' name = name1 print('相似度为:%.2f' % score) print("欢迎%s!" % name) time.sleep(0.5) if name == 'lin_xiu_li': name2 = '小莉' name = name2 print('相似度为:%.2f' % score) print("欢迎%s!" % name) time.sleep(0.5) if name == "qin_wen_hua": name3 = '小华' name = name3 print('相似度为:%.2f' % score) print("欢迎%s!" % name) time.sleep(0.5) else: print('相似度为:%.2f' % score) print("抱歉,识别失败!请重试!") name = 'Unknow' return 0 #curren_time = time.asctime(time.localtime(time.time()))#获取当前时间 curren_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') #将人员出入的记录保存到Log.txt中 f = open('ming_dan.txt','a') f.write("姓名:" + name + " " + "时间:" + str(curren_time)+'\n') f.close() return 1 if result['error_msg'] == 'pic not has face': print('检测不到人脸') time.sleep(1) return 0 else: print(result['error_code']+' ' + result['error_code']) return 0 #主函数 if __name__ == '__main__': a = 0 #while True: while a < 2: print('准备') if True: getimage()#拍照 img = transimage()#转换照片格式 res = go_api(img)#将转换了格式的图片上传到百度云 if(res == 1):#是人脸库中的人 print("开门") else: print("关门") print('稍等三秒进入下一个') time.sleep(1) a += 1
这四种方法都是本人所尝试过的,但由于自身能力还是有所不足,有些地方写得或描述得不是很好,还望见谅。
可能有个bug,就是手机上的CSDN APP在显示代码时不显示完整,许多都会下面一半代码就空了,但是在电脑网页上代码却是显示完整的。
##2020.8.30
(该文章用于给自己今年所经历的,做一个总结和回忆)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。