文章目录
一、项目介绍
二、环境配置
三、项目知识储备
项目介绍
人脸识别在现代化中应用较为广泛,比如人脸考勤系统等,银行卡人脸验证,手机面部识别等,顾名思义它也是一个分类系统,所以我们利用Python 调用opencv得分类器进行面部识别。
环境配置
操作系统: Windows
程序语言: Python 3.9.5(64-bit)安装步骤:[Python 的下载安装与配置(针对新手)_无限嚣张(菜菜)的博客-CSDN博客
1.进入官网:www.python.org/downloads/,点击Downloads Python 3.11.1 (个人觉得只要3的版本都行,根据自己的需求)6.点击win+R,输入cmd,输入Python,显示3.11.1,说明python 安装成功。7.测试代码:输入print("hello student"),最后quit(),退出。4.将下边框选中,点击 install。5.显示安装成功,点击关闭。
https://blog.csdn.net/zywcxz/article/details/128277213?spm=1001.2014.3001.5501](https://blog.csdn.net/zywcxz/article/details/128277213?spm=1001.2014.3001.5501 "Python 的下载安装与配置(针对新手)_无限嚣张(菜菜)的博客-CSDN博客")开发环境: Pycharm 安装步骤:
[Python 开发环境的下载与配置以及anconda3在pycharm的配置_无限嚣张(菜菜)的博客-CSDN博客
Python 开发环境的下载与配置以及anconda3在pycharm的配置
https://blog.csdn.net/zywcxz/article/details/128284292?spm=1001.2014.3001.5501](https://blog.csdn.net/zywcxz/article/details/128284292?spm=1001.2014.3001.5501 "Python 开发环境的下载与配置以及anconda3在pycharm的配置_无限嚣张(菜菜)的博客-CSDN博客") opencv: 安装步骤:1.win+r
2.在窗口输入cmd,回车
3.输入pip install opencv-python,如下正在安装中,稍等片刻
这个版本比较弱,我们后期到了检测环节是无法实现的,需要安装Ooen-cv软件
进入官网——Home - OpenCV
下载OpenCV-4.6.0版本
项目知识储备
导入图片
首先利用Python的cv模块,对图像进行读取
# 导入cv模块import cv2 as impage# 读取图片img = impage.imread('cat.jpg')# 显示图片impage.imshow('read_img', img)# 等待impage.waitKey(0)# 释放内存impage.destroyAllWindows()
效果如下:
灰度转换
# 导入cv模块import cv2 as impage# 读取图片img = impage.imread('cat.jpg')# 灰度转换grey_scale_img = impage.cvtColor(img, impage.COLOR_BGR2GRAY)# 显示灰度图片impage.imshow('gray', grey_scale_img)# 保存灰度图片impage.imwrite('gray_face1.jpg', grey_scale_img)# 显示图片impage.imshow('read_img', img)# 等待impage.waitKey(0)# 释放内存impage.destroyAllWindows()
效果如下,可知它的图形颜色已经发生变化
修改图片尺寸的大小
import cv2 as impage# 读取图片img = impage.imread('cat.jpg')# 修改尺寸Modify_size_img = impage.resize(img, dsize=(200, 200))# 显示原图impage.imshow('img', img)# 显示修改后的impage.imshow('resize_img', Modify_size_img)# 打印原图尺寸大小print('修改前:', img.shape)# 打印修改后的大小print('修改后:', Modify_size_img.shape)# 等待while True: if ord('q') == impage.waitKey(0): break# 释放内存impage.destroyAllWindows()
通过下图明显可知图片尺寸已经发生改变
接下来,我们打印输出,看其图片大小,可知修改前图片大小尺寸为:(548,400,3),修改以后的尺寸为:(200,200,3)
如果我们检测到人脸以后需要画框,所以需要绘制矩形
矩形检测框图绘制
# 导入cv模块import cv2 as image# 读取图片img = image.imread('cat.jpg')# 坐标x, y, w, h = 100, 100, 100, 100# 绘制矩形image.rectangle(img, (x, y, x + w, y + h), color=(0, 0, 255), thickness=5)# 绘制圆形image.circle(img, center=(x + w, y + h), radius=100, color=(255, 0, 0), thickness=5)# 显示image.imshow('re_img', img)while True: if ord('q') == image.waitKey(0): break# 释放内存image.destroyAllWindows()
效果如下:
人脸检测识别
# 导入cv模块import cv2 as impage# 检测函数def face_detect_demo(): gary = impage.cvtColor(img, impage.COLOR_BGR2GRAY) # 调用opencv的分类器 face_detect = impage.CascadeClassifier( 'C:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml') face = face_detect.detectMultiScale(gary, 1.01, 5, 0, (50, 50), (300, 300)) for x, y, w, h in face: impage.rectangle(img, (x, y), (x + w, y + h), color=(0, 0, 255), thickness=2) impage.imshow('result', img)# 读取图像img = impage.imread('cat.jpg')# 检测函数face_detect_demo()# 等待while True: if ord('q') == impage.waitKey(0): break# 释放内存impage.destroyAllWindows()
利用opencv中的人脸分类器进行分类识别,我们调用opencv里边的分类器
我们设置在低于(50,50)之内不可能有人脸,在大于(300,300)之外也不可能有人脸。标框如下:
多个人脸检测效果
# 导入cv模块import cv2 as cv# 检测函数def face_detect_demo(): gary = cv.cvtColor(img, cv.COLOR_BGR2GRAY) face_detect = cv.CascadeClassifier('C:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml') face = face_detect.detectMultiScale(gary) for x, y, w, h in face: cv.rectangle(img, (x, y), (x + w, y + h), color=(0, 0, 255), thickness=2) cv.imshow('result', img)# 读取图像img = cv.imread('face2.jpg')# 检测函数face_detect_demo()# 等待while True: if ord('q') == cv.waitKey(0): break# 释放内存cv.destroyAllWindows()
我们不能做到百分百的检测效果,我们通过修改参数可以做到,但是修改参数以后,我们仅仅是局限于这张图片,所以我们需要对人脸图片进行训练,最后识别。
对人脸视频进行检测
# 导入cv模块import cv2 as cv# 检测函数def face_detect_demo(img): gary = cv.cvtColor(img, cv.COLOR_BGR2GRAY) face_detect = cv.CascadeClassifier('C:/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml') face = face_detect.detectMultiScale(gary) for x, y, w, h in face: cv.rectangle(img, (x, y), (x + w, y + h), color=(0, 0, 255), thickness=2) cv.imshow('result', img)cap = cv.VideoCapture(0)while True: flag, frame = cap.read() if not flag: break face_detect_demo(frame) if ord('q') == cv.waitKey(1): break# 释放内存cv.destroyAllWindows()# 释放摄像头cap.release()
具体摄像头识别,有需要自己玩就可以,本人亲自测试,可以调用摄像头使用。
数据集录入
首先开启摄像头,然后显示每一帧图像,最后通过按键检测,如果检测到字符串“s”,则将图片保存到对应的目录下,如果检测到空格,则退出
# 导入模块import cv2 as impage# 摄像头cap = impage.VideoCapture(0)falg = 1num = 1while (cap.isOpened()): # 检测是否在开启状态 ret_flag, V_show = cap.read() # 得到每帧图像 impage.imshow("Capture_Test", V_show) # 显示图像 k = impage.waitKey(0) & 0xFF # 按键判断 if k == ord('s'): # 保存 impage.imwrite("C:/test/test1" + str(num) + ".jpg", V_show) print("success to save" + str(num) + ".jpg") print("-------------------") num += 1 elif k == ord(' '): # 退出 break# 释放摄像头cap.release()# 释放内存impage.destroyAllWindows()
如下可知我们保存到目录下的图片为20张:
训练数据
我们把刚才拍照的图片导入进来,作为训练集,
import osimport cv2import sysfrom PIL import Imageimport numpy as npdef getImageAndLabels(path): facesSamples = [] ids = [] imagePaths = [os.path.join(path, f) for f in os.listdir(path)] # 检测人脸 face_detector = cv2.CascadeClassifier('C:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml') # 打印数组imagePaths print('数据排列:', imagePaths) # 遍历列表中的图片 for imagePath in imagePaths: # 打开图片,黑白化 PIL_img = Image.open(imagePath).convert('L') # 将图像转换为数组,以黑白深浅 # PIL_img = cv2.resize(PIL_img, dsize=(400, 400)) img_numpy = np.array(PIL_img, 'uint8') # 获取图片人脸特征 faces = face_detector.detectMultiScale(img_numpy) # 获取每张图片的id和姓名 id = int(os.path.split(imagePath)[1].split('.')[0]) # 预防无面容照片 for x, y, w, h in faces: ids.append(id) facesSamples.append(img_numpy[y:y + h, x:x + w]) # 打印脸部特征和id # print('fs:', facesSamples) print('id:', id) # print('fs:', facesSamples[id]) print('fs:', facesSamples) # print('脸部例子:',facesSamples[0]) # print('身份信息:',ids[0]) return facesSamples, idsif __name__ == '__main__': # 图片路径 path = "C:/test/test1" # 获取图像数组和id标签数组和姓名 faces, ids = getImageAndLabels(path) # 加载识别器 recognizer = cv2.face.LBPHFaceRecognizer_create() # 训练 recognizer.train(faces, np.array(ids)) # 保存文件 # recognizer.write('trainer/trainer.yml') # save_to_file('names.txt',names)
人脸识别过程
import cv2import numpy as npimport os# coding=utf-8import urllibimport urllib.requestimport hashlib#加载训练数据集文件recogizer=cv2.face.LBPHFaceRecognizer_create()recogizer.read('trainer/trainer.yml')names=[]warningtime = 0def md5(str): import hashlib m = hashlib.md5() m.update(str.encode("utf8")) return m.hexdigest()statusStr = { '0': '短信发送成功', '-1': '参数不全', '-2': '服务器空间不支持,请确认支持curl或者fsocket,联系您的空间商解决或者更换空间', '30': '密码错误', '40': '账号不存在', '41': '余额不足', '42': '账户已过期', '43': 'IP地址限制', '50': '内容含有敏感词'}def warning(): smsapi = "http://api.smsbao.com/" # 短信平台账号 user = '13******10' # 短信平台密码 password = md5('*******') # 要发送的短信内容 content = '【报警】\n原因:检测到未知人员\n地点:xxx' # 要发送短信的手机号码 phone = '*******' data = urllib.parse.urlencode({'u': user, 'p': password, 'm': phone, 'c': content}) send_url = smsapi + 'sms?' + data response = urllib.request.urlopen(send_url) the_page = response.read().decode('utf-8') print(statusStr[the_page])#准备识别的图片def face_detect_demo(img): gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转换为灰度 face_detector=cv2.CascadeClassifier('D:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml') face=face_detector.detectMultiScale(gray,1.1,5,cv2.CASCADE_SCALE_IMAGE,(100,100),(300,300)) #face=face_detector.detectMultiScale(gray) for x,y,w,h in face: cv2.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2) cv2.circle(img,center=(x+w//2,y+h//2),radius=w//2,color=(0,255,0),thickness=1) # 人脸识别 ids, confidence = recogizer.predict(gray[y:y + h, x:x + w]) #print('标签id:',ids,'置信评分:', confidence) if confidence > 80: global warningtime warningtime += 1 if warningtime > 100: warning() warningtime = 0 cv2.putText(img, 'unkonw', (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1) else: cv2.putText(img,str(names[ids-1]), (x + 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 1) cv2.imshow('result',img) #print('bug:',ids)def name(): path = './data/jm/' #names = [] imagePaths=[os.path.join(path,f) for f in os.listdir(path)] for imagePath in imagePaths: name = str(os.path.split(imagePath)[1].split('.',2)[1]) names.append(name)cap=cv2.VideoCapture('1.mp4')name()while True: flag,frame=cap.read() if not flag: break face_detect_demo(frame) if ord(' ') == cv2.waitKey(10): breakcv2.destroyAllWindows()cap.release()#print(names)
注:项目来源参考于微信公众号:竞赛空间,最终项目解释权来源于:竞赛空间