在过去的十年里,深度学习(DL)在许多领域取得了巨大的成功。目前最先进的人脸识别系统能够在图像和视频中识别人脸,其精度与人类相当,甚至更高。本系列文章分为两部分:第一部分是人脸检测,客户端应用程序在图像或视频流中检测人脸,对检测到的人脸图片进行对齐,并将它们提交给服务器;第二部分是人脸识别,服务器端应用程序执行人脸识别。假设您已经熟悉DNN、Python、Keras和TensorFlow。欢迎您下载本项目的代码以跟随实践。
让从创建容器的镜像开始。将使用Docker Desktop软件来管理镜像和容器。可以从头开始创建应用程序的镜像,但基于现有的AI容器创建镜像更快、更容易。对来说最合适的是预装了最新版本TensorFlow框架的TensorFlow容器。首先,必须将镜像下载到PC上:
docker pull tensorflow/tensorflow:latest-gpu-jupyter
下载镜像后,可以在Docker Desktop的“Images”标签页中看到它。点击“Run”按钮运行容器。
下一步是配置容器以启动人脸识识别服务器。在“Containers/Apps”标签页中,为容器运行一个终端窗口。使用以下命令安装Keras框架和MTCNN库:
# pip install keras
# pip install mtcnn
成功安装的日志如下图所示。请注意,安装MTCNN库时会附带安装最新版本的Python OpenCV框架。只需要添加libGL库以确保完整性:
# apt install libgl1-mesa-glx
将使用Flask微框架来构建Web API。需要使用简单的pip命令安装这个框架以及jsonpickle包:
# pip install Flask
# pip install jsonpickle
class VideoFR:
def __init__(self, detector, rec, f_db):
self.detector = detector
self.rec = rec
self.f_db = f_db
def process(self, video, align=False, save_path=None):
detection_num = 0
rec_num = 0
capture = cv2.VideoCapture(video)
img = None
frame_count = 0
dt = 0
if align:
fa = Face_Align_Mouth(160)
# Capture all frames
while True:
(ret, frame) = capture.read()
if frame is None:
break
frame_count = frame_count + 1
faces = self.detector.detect(frame)
f_count = len(faces)
detection_num += f_count
names = None
if (f_count > 0) and (not (self.f_db is None)):
t1 = time.time()
names = [None] * f_count
for (i, face) in enumerate(faces):
if align:
(f_cropped, f_img) = fa.align(frame, face)
else:
(f_cropped, f_img) = self.detector.extract(frame, face)
if (not (f_img is None)) and (not f_img.size == 0):
embds = self.rec.embeddings(f_img)
data = self.rec.recognize(embds, self.f_db)
if not (data is None):
rec_num += 1
(name, dist, p_photo) = data
conf = 1.0 - dist
names[i] = (name, conf)
print("Recognized: " + name + " " + str(conf))
if not (save_path is None):
percent = int(conf * 100)
ps = ("%03d" % rec_num) + "_" + name + "_" + ("%03d" % percent) + ".png"
ps = os.path.join(save_path, ps)
cv2.imwrite(ps, f_img)
t2 = time.time()
dt = dt + (t2 - t1)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if dt > 0:
fps = detection_num / dt
else:
fps = 0
return (detection_num, rec_num, fps)
在类的process方法中,移除了显示带有OpenCV窗口的帧的代码。还添加了save_path参数,指定保存识别到的人脸图片的位置。
现在可以在终端中使用以下命令运行Python代码:
python /home/pi_fr/pi_fr_facenet.run_align_dock.lnx.py /home/pi_fr/video/5_1.mp4