Django实战(8)——在线人脸识别系统demo(对接Redis、初步实现人脸识别功能)
接着上一篇Django实战(7)——在线人脸识别系统(第一步、实现图片上传和MySQL数据库的对接,ORM操作数据库)https://blog.csdn.net/qq_41938259/article/details/104562046写:
这是Github地址:https://gitee.com/timtian139/WEBfaceRecognitionTest
上一篇用Django实现了图片上传和人名信息的录入,使用的是MySQL对接的,由于名字对应图片,完全可以用Redis的String键值对来替代MySQL的功能。而且这一次将之前一篇博文https://blog.csdn.net/qq_41938259/article/details/104482152 (人脸识代码第一版)的人脸识别功能引入,从Redis中读取数据,进行识别。这里我新建了一个app名为camera,顾名思义就是打开摄像机进行人脸识别的意思。
以下是camera这个app的views.py文件内容:
import cv2
import pyttsx3
import face_recognition
import numpy as np
import redis
from django.shortcuts import render
def home(request):
return render(request, 'home.html')
def camera(request):
face_cascade = cv2.CascadeClassifier(
"C:\\Users\\TIM\\cascades\\haarcascade_frontalface_default.xml")
red = redis.StrictRedis(host='localhost', port=6379, db=1)
camera = cv2.VideoCapture(0)
while True:
# 参数ret 为True 或者False,代表有没有读取到图片
# 第二个参数frame表示截取到一帧的图片
ret, frame = camera.read()
# frame = cv2.imread(r'C:\Users\TIM\c.jpg')
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
face = face_cascade.detectMultiScale(gray, 1.5, 3)
for (x, y, w, h) in face:
# 绘制矩形框,颜色值的顺序为BGR,即矩形的颜色为蓝色
img = cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
roi_gray = gray[y:y + h, x:x + w]
roi_color = frame[y:y + h, x:x + w]
# 在检测到的人脸区域内检测眼睛
# eyes = eye_cascade.detectMultiScale(roi_gray)
# for (ex, ey, ew, eh) in eyes:
# cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
cv2.imshow('camera', frame)
k = cv2.waitKey(1)
if k == ord('s'):
rgb_frame = frame[:, :, ::-1]
# 获取画面中的所有人脸位置及人脸特征码
face_locations = face_recognition.face_locations(rgb_frame)
face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)
# 对获取的每个人脸进行识别比对
flag = False
for (top, right, bottom, left), face_encoding in list(zip(face_locations, face_encodings)):
print(face_encoding)
print(face_encoding.shape)
# 对其中一个人脸的比对结果(可能比对中人脸库中多个人脸)
# keys = red.keys()
# for key in keys:
# image = face_recognition.load_image_file(red.get(key))
# face_encoding = face_recognition.face_encodings(image)[0]
# namelist = []
# namelist.append(key)
faces = red.keys()
for face in faces:
image = face_recognition.load_image_file(red.get(face))
face_encodings = face_recognition.face_encodings(image)[0]
print(np.array(face_encodings).shape)
print([np.array(face_encodings)])
matches = face_recognition.compare_faces([np.array(list(face_encodings))],
face_encoding, tolerance=0.40)
print(matches)
if True in matches:
engine = pyttsx3.init()
engine.say('你好,{}'.format(face.decode('utf-8')))
engine.runAndWait()
flag = True
break
if flag is False:
engine = pyttsx3.init()
engine.say('无法识别')
engine.runAndWait()
if k == ord('q'):
break
camera.release()
return render(request, 'home.html')
这个文件就是人脸识别的核心。
可以看到现在urls.py文件多了两个url,如下所示。
from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from faceDataManagement.views import data, upload_file, index
from camera.views import camera, home
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', index),
url(r'^data/', data),
url(r'^uploadFile/', upload_file),
url(r'^camera/', camera),
url(r'^$', home)
home是主页,而camera是人脸识别功能的核心代码的映射。
这是主页home的html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<a href="/index/">上传图片到人脸识别库</a>
<hr>
<a href="/camera/">人脸识别页</a>
</body>
</html>
这是camera的html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>display</title>
</head>
<body>
<!DOCTYPE html>
<html lang="en">
<head>
<link href="favicon.ico" rel="shortcut icon">
<meta charset="UTF-8">
<title>上传照片</title>
</head>
<body>
<form enctype="multipart/form-data" action="/camera/" method="GET">
<li>人脸检测</li>
<li>按S识别,按退出</li>
</form>
</body>
</html>
对于Redis的对接,要把原来的faceDataManagement的app中的views.py文件改一下:
def upload_file(request):
if request.method == "POST": # 请求方法为POST时,进行处理
myFile = request.FILES.get("myfile", None) # 获取上传的文件,如果没有文件,则默认为None
if not myFile:
return HttpResponse("no files for upload!")
destination = open(os.path.join('facePhoto', myFile.name), 'wb+') # 打开特定的文件进行二进制的写操作
for chunk in myFile.chunks(): # 分块写入文件
destination.write(chunk)
destination.close()
# 这一段是用orm将数据存入MySQL
pictureLocation = os.path.join('facePhoto', myFile.name)
data = Name_Picture()
data.picture = pictureLocation
username = request.POST['username']
data.names = username
data.save()
# 此步骤是存入Redis
red.set(username, pictureLocation)
return HttpResponseRedirect('/index/')
elif request.method == 'GET':
return render(request, 'index.html')
END