本文是"基于flask+opencv+sklearn+tensorflow人脸识别系统"的续篇,主要说明在线进行人脸识别,主要分为超级链接人脸识别、图片上抟人脸识别、网页摄像人脸识别等内容。
一 、超级链接人脸识别
首先在项目的template目录下新建首页index.html,并在网页body标签内使用以下代码:
<div align="center">
<h2>在线人脸识别</h2>
<a href="/she/">打开摄像头识别</a>
<p style='color:red'>请按键盘上的p键停止摄像头识别</p>
</div>
效果如下所示:
其次在项目下新建main.py文件,主要使用Flask框架完成首页和“/she/”两个web访问路由,并在“/she/”访问路由下完成人脸识别,代码如下所示:
from flask import Flask,render_template
from cameraDemo import Camera_reader
app=Flask(__name__)
@app.route('/',methods=['POST','GET'])
def init():
return render_template('index.html',title='Home')
@app.route('/she/')
def she():
camera=Camera_reader()
camera.build_camera()
return render_template('index.html',title='Home')
if __name__ =='__main__':
app.run(debug=True)
注意:人脸识别窗口关闭需要按键盘上的P键。
二 、图像上传人脸识别
首先在首页index.html中的body标签中构建一个文件上传表单,新增主要代码如下:
<form action="/" method="post" enctype="multipart/form-data">
上传文件<input type="file" name="photo" >
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
效果如下:
其次,在main.py增加接收上传文件代码,并将结果通过show.html网页将上传图片和结果展现出来,新增主要代码如下::
def read_name_list(path):
"读取训练数据集"
name_list=[]
for child_dir in os.listdir(path):
name_list.append(child_dir)
return name_list
def detectOnePicture(path):
"单图识别"
model=Model()
model.load()
img=cv2.imread(path)
img=cv2.resize(img,(128,128))
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
picType,prob=model.predict(img)
if picType !=-1:
name_list=read_name_list('dataset/')
print(name_list[picType],prob)
res=u"识别为:"+name_list[picType]+u"概率为: "+str(prob)
else:
res=u"抱歉,未识别该人,请尝试增加数据量来训练模型"
return res
@app.route('/',methods=['POST','GET'])
def init():
if request.method=='POST' and 'photo' in request.files:
img_file=request.files.get('photo')
file_name=img_file.filename
#文件名安全转换
filename=secure_filename(file_name)
img_file.save(os.path.join(UPLOAD_PATH,filename))
res= detectOnePicture(os.path.join(UPLOAD_PATH,filename))
return render_template('show.html',res=res,filename=filename)
return render_template('index.html',title='Home')
最后 ,通过shotw.html网页展现最终结果,代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<title>在线人脸识别</title>
</head>
<body>
<div align="center">
<h2>在线人脸识别</h2>
<p> <img style='border:solid 2px blue' src="static/images/{{filename}}"></p>
<p style='font-size: 32px;color:red'>{{res}}</p>
<a href="http://localhost:5000">返回首页</a>
</div>
</body>
</html>
网页主要展示上传图片和最终识别结果。
三、网页摄像人脸识别
1、前端功能
首先创建网页文件camera.html,此文件负责打开摄像头,关闭摄像头,人脸识别,下载图片四个功能模块,代码如下所示:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<title>远程在线识别</title>
<script>
//定义一个mediaStream对象
let mediaStream;
// 判断浏览器是否支持HTML5 Canvas
window.onload = function () {
try {
//动态创建一个canvas元 ,并获取他2Dcontext。如果出现异常则表示不支持 document.createElement("canvas").getContext("2d");
document.getElementById("support").innerHTML = "浏览器支持HTML5 CANVAS";
}
catch (e) {
document.getElementByIdx("support").innerHTML = "浏览器不支持HTML5 CANVAS";
}
};
function getMedia(){
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
video = document.getElementById("video"),
videoObj = { "video": true },
errBack = function (error) {
console.log("Video capture error: ", error.code);
};
setInterval(function(){
context.drawImage(video, 0, 0, 480, 320)
},100);
if(navigator.getUserMedia){
navigator.getUserMedia(videoObj, function (stream) {
mediaStream=stream;
video.srcObject = stream;
video.play();
}, errBack);
} else if(navigator.webkitGetUserMedia) {
navigator.webkitGetUserMedia(videoObj, function (stream) {
mediaSteam=stream;
video.src = window.webkitURL.createObjectURL(stream);
video.play();
}, errBack);
}
}
//停止媒体播放
function stopMedia(){
if(mediaStream){
mediaStream.getTracks().forEach(function(track) {
track.stop(); // 停止所有跟踪
});
}
mediaStream=null; //重置stream
}
function capture(){
const canvas=document.getElementById("canvas");
const dataURL=canvas.toDataURL('image/jpeg');
fetch('/upload_canvas',{
method: 'POST',
headers: {
'Content-Type':'application/json'
},
body: JSON.stringify({image: dataURL})
}).then(response=>response.json())
.then(data=>{
document.getElementById('result').innerHTML=data.result
console.log('Success',data);
})
.catch(error=>{
console.log('Error:',error)
})
}
function download(){
//获取base64格式图像数据
let imgBase64=document.getElementById('canvas').toDataURL('image/jpeg')
let alink=document.createElement('a')
alink.href=imgBase64
alink.download='image.jpg'
alink.click()
}
</script>
</head>
<body>
<div align="center">
<div id="support"></div>
<div>
<video id="video" autoplay="autoplay" width="480" height="320" style="display:none;"></video>
<canvas id="canvas" width="480" height="320"></canvas>
<p id="result"></p>
</div>
<div>
<button onclick="getMedia()">开启摄像头</button>
<button onclick="stopMedia()">关闭摄像头</button>
<button onclick="capture()">人脸识别k</button>
<button onclick="download()">下载图片</button>
</div>
</div>
</body>
</html>
其 中,getMedia()函数,先设置每100毫秒复制video标签内容到canvas标签中,再使用webrtc打开摄像头,并把vidoeo标签的srcObject属性设置为摄像媒体流,开启自动播放。stopMedia()函数 借助全局变量mediaStream关闭摄像功能。download()函数先从canvas标签中获取图像数据 ,再创建动态的超链接alink,赋值以相应属性,最后执行单击事件完成下载。
capture()函数,首先获取画布中的数据,并使用异步传输模式ajax的Post方式传递图像数据至后台的“/upload_canvas”,当数据传递成功时,在id为result标签内显示最终识别结果,数据传递失败在控制台输出错误信息。
2、后端功能
后台主要是在maim.py模块中“uplocad_canvas”处理前端所传数据 ,其功能分为获取前羰所传数据 ,处理图像数据,保存图像,识别图像,传递图像识别结果至前端。其代码如下所示:
@app.route('/upload_canvas',methods=['POST'])
def upload_canvas():
data=request.json
image_data=data['image']
#去前缀'data:image/jpeg;base64;'
image_data=image_data.split(",")[1]
#解码base64数据
image_data=base64.b64decode(image_data)
#数据转换为图像
image=Image.open(BytesIO(image_data))
#保存图像
image.save('static/images/uploaded_image.jpg')
res= detectOnePicture(os.path.join(UPLOAD_PATH,'uploaded_image.jpg'))
return jsonify({'result': res})
其效果如下:
本文主要介绍了flask作为后端框架,前端以html+css+javascript完成人脸识别,其中超级链接人脸识别直接调用后端的 cameraDemo模块,完成人脸识别;只能本机使用,图像上传人脸识别在后端识别上传的图像,并在前端展示上传图像和识别结果;网页摄像人脸识别在线使用摄像头动态捕捉人像传递至后端,后端接收数据并识别,传递识别结果至前端显示。后两种识别方式可以远程使用。