🐚作者简介:苏凉(专注于网络爬虫,数据分析) 🐳博客主页:苏凉.py的博客 🌐系列专栏:python-opencv快速入门 👑名言警句:海阔凭鱼跃,天高任鸟飞。 📰要是觉得博主文章写的不错的话,还望大家三连支持一下呀!!! 👉关注✨点赞👍收藏📂
文章目录 前言 人脸信息录入保存(动图演示) 数据训练 1.导入模块 2.定义一个人脸检测函数 2.1 定义列表来存放图像id和图像数据 2.2 导入联级分类器 2.3 遍历列表中的图片并对其进行处理 2.3.1 将图片灰度化,并将其转换为数组 2.3.2 获取人脸特征和id以及姓名 2.3.3 预防无效照片 2.3 打印id和图像数组数据 3.调用函数并对人脸进行训练并将数据保存为yml文件 人脸识别小案例 结语
前言 在上一篇文章中我们主要了解到用opencv如何对人脸进行检测,以及对多个人脸进行检测和摄像头检测等操作。那么这篇文章主要给大家介绍如何用opencv进行人脸信息录入,数据训练,人脸识别 等操作。话不多说,直接进入正题!! ⚜上期传送锚点: 🛸 利用opencv带你玩转人脸识别-上篇(读取图片,灰度转换,尺寸修改,绘制矩形快速入门) 🛸利用opencv带你玩转人脸识别-中篇(人脸检测,检测多个,视频检测快速入门)
人脸信息录入保存(动图演示) 在上一篇中我们学习了如何调用摄像头来获取摄像头下的画面进行人脸检测,那么现在我们就 将摄像头下的图像进行保存,进而可以进行下一步的数据清洗操作。
import cv2 as cv cap = cv. VideoCapture( 0 ) num = 1 flag = 1 while ( cap. isOpened( ) ) : cap_flag, Vshow = cap. read( ) cv. imshow( 'testface' , Vshow) a = cv. waitKey( 0 ) if a == ord ( 's' ) : cv. imwrite( './saveface/number' + str ( num) + '.jpg' , Vshow) print ( '第' + str ( num) + '张保存完毕!!' ) num = num + 1 elif a == ord ( ' ' ) : break cap. release( ) cv. destroyAllWindows( )
效果展示:
数据训练 上面我们进行了信息的录入,而在这里我们需要对数据进行数据清洗,并且将人物的名字和id提取出来,将图片的没一处用灰度数据表示出来,其中数字越大则灰度越高。
1.导入模块 这里遇到numpy模块,将图像转换为一组数组表示。 os模块则是对文件/目录的读取操作
import osimport cv2from PIL import Imageimport numpy as np
2.定义一个人脸检测函数 def getImageAndLabels ( path) :
2.1 定义列表来存放图像id和图像数据 facesSamples= [ ] ids= [ ] imagePaths= [ os. path. join( path, f) for f in os. listdir( path) ]
2.2 导入联级分类器 分类器的路径在之前有指出。不知道在哪的小伙伴可以参考上一篇文章。
face_detector = cv2. CascadeClassifier( 'D:/test001/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml' )
2.3 遍历列表中的图片并对其进行处理 for imagePath in imagePaths:
2.3.1 将图片灰度化,并将其转换为数组 灰度化图片,PIL有九种不阿模式:1,L,P,RGB,RGBA,CMYK,YCbCr,I ,F。
PIL_img= Image. open ( imagePath) . convert( 'L' ) img_numpy= np. array( PIL_img, 'uint8' )
2.3.2 获取人脸特征和id以及姓名 faces = face_detector. detectMultiScale( img_numpy) id = int ( os. path. split( imagePath) [ 1 ] . split( '.' ) [ 0 ] )
2.3.3 预防无效照片 for x, y, w, h in faces: ids. append( id ) facesSamples. append( img_numpy[ y: y+ h, x: x+ w] )
2.3 打印id和图像数组数据 print ( 'id:' , id ) print ( 'fs:' , facesSamples) return facesSamples, ids
3.调用函数并对人脸进行训练并将数据保存为yml文件 if __name__ == '__main__' : path= './data/' faces, ids= getImageAndLabels( path) recognizer= cv2. face. LBPHFaceRecognizer_create( ) recognizer. train( faces, np. array( ids) ) recognizer. write( './trainer.yml' )
4.完整代码及运行结果 import osimport cv2from 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( 'D:/test001/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml' ) for imagePath in imagePaths: PIL_img= Image. open ( imagePath) . convert( 'L' ) img_numpy= np. array( PIL_img, 'uint8' ) faces = face_detector. detectMultiScale( img_numpy) 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] ) print ( 'id:' , id ) print ( 'fs:' , facesSamples) return facesSamples, idsif __name__ == '__main__' : path= './data/' faces, ids= getImageAndLabels( path) recognizer= cv2. face. LBPHFaceRecognizer_create( ) recognizer. train( faces, np. array( ids) ) recognizer. write( './trainer.yml' )
运行结果:
人脸识别小案例 案例陈述:提前录入人脸,并进行数据训练,之后对人脸进行识别,登录一个网页,若识别的人脸不在数据训练则登录失败,若识别到正确人脸则在图像上输入人脸名字。
import cv2import osimport urllibimport urllib. request recogizer= cv2. face. LBPHFaceRecognizer_create( ) recogizer. read( './trainer.yml' ) names= [ ] warningtime = 0 def md5 ( str ) : import hashlibm = 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?' + dataresponse = 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:/test001/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml' ) face= face_detector. detectMultiScale( gray, 1.1 , 5 , cv2. CASCADE_SCALE_IMAGE, ( 100 , 100 ) , ( 300 , 300 ) ) 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] ) if confidence > 80 : global warningtimewarningtime += 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) def name ( ) : path = './data/' 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 ) : break cv2. destroyAllWindows( ) cap. release( )
运行结果(在没有对人脸进行数据训练之前): 在对人脸导入并进行数据训练之后会识别到姓名: 在对没有人脸数据训练的情况下显示密码错误:
结语 到这里我们的人脸识别就结束啦,下期带大家一起整理opencv总体的基础用法,前面三篇主要带大家了解并快速入门,后续更新它的基础方法。 关注我,咱们下期再见!!