这里写自定义目录标题
从零开始写高性能的人脸识别服务器(三)
我们在前两章学习了高性能的服务器高性能在哪里,下面开始着手Coding,其实Coing很简单,主要是学习和理解netty和protobuf比较难。github仓库地址
1 消息格式
消息序列化使用protobuf。在传输过程中为了极大的提高效率,直接传输的图像的像素点。服务器响应的数据格式参考的是HTTP的状态码。但是业务量比较少嘛,也没有啥提现。
1.1 定义Proto
(1)图片的消息格式。ImageProto消息,即客户端给服务端的消息
syntax = "proto3"; // proto3 必须加此注解
option java_package = "xin.marico.facerecogition.entity";
option java_outer_classname = "ImageProto";
message Image {
string personName = 1;
repeated int32 data = 2; //存储图像的像素数据,相当于int数组
int32 cols = 3; //图像的宽度
int32 rows = 4;//图像的高度
}
(2)相应消息格式,即服务端给客户端回复的消息
syntax = "proto3"; // proto3 必须加此注解
option java_package = "xin.marico.facerecogition.entity";
message ResultProto {
int32 status = 1; //消息状态码
string message = 2;//消息体
}
1.2 编译
protoc.exe对消息格式进行编译。
(1)编译成Java类
D:\protobuf-3.11.2\protoc-3.11.2-win64\bin>protoc.exe --java_out=./FaceRecoginition ImageProto.proto
(2)编译成C++类
D:\protobuf-3.11.2\protoc-3.11.2-win64\bin>protoc.exe --cpp_out=./FaceRecoginition ImageProto.proto
2 人脸识别微服务
Python人脸识别程序,不断监听Redis的队列,从Redis队列里面取出数据进行处理。数据格式为imgKey_resultKey,imgKey是图像存在redis中存储的key值,resultKey是Netty监听的Redis的key。
人脸上传的原理是,将首先在图片中检测出人脸的位置,将人脸抠出来,进行编码,将编码存储在Redis数据库。
人脸识别的原理是对要识别的人脸进行编码,然后将得到的编码信息与人脸库中的信息进行比对,返回最符合的人脸信息。下面是具体代码。
# -*- coding: utf-8 -*-
import face_recognition
import sys
import redis
from datetime import datetime
import time
from PIL import Image
import os
import uuid
import numpy as np
from numpy import float64
import json
from multiprocessing import Process
from multiprocessing import Pool
def recognize_face(megQueueStr):
print("开始人脸识别的进程,监听消息队列:",megQueueStr)
redisCli = redis.StrictRedis(host='127.0.0.1', port=6379)
while(True):
queueMsg = redisCli.lpop(megQueueStr)
time.sleep(0.001)
if queueMsg is not None:
print("识别人脸...")
queueMsg = str(queueMsg, encoding='UTF-8')
imgKey, resultKey = queueMsg.split("_")
result_status = 200
result_msg = ""
# 1.加载未知人脸图片
redisCli = redis.Redis(host='127.0.0.1', port=6379)
cols = int(redisCli.hget(imgKey, "cols"))
rows = int(redisCli.hget(imgKey, "rows"))
data = redisCli.hget(imgKey, "data")
unknown_face = np.array(json.loads(data), dtype=np.uint8)
unknown_face = unknown_face.reshape(rows, cols, 3)
redisCli.delete(imgKey)
# 2.对未知人脸图片进行编码
unknown_face_encodings = face_recognition.face_encodings(unknown_face)
if len(unknown_face_encodings) == 0:
redisCli.set(resultKey, str(500) + "_" + "未检测到人脸")
continue
unknown_face_encoding = unknown_face_encodings[0]
# 3.加载所有已知人脸
known_faces_encoding = []
face_infos = redisCli.lrange('face_infos', 0, -1)
for face_info in face_infos:
face_info = eval(str(face_info, encoding='utf-8'))
face_encoding = np.array(json.loads(face_info

本文介绍了一个高性能人脸识别服务器的实现过程,包括使用protobuf进行消息格式定义与编译、基于Python的人脸识别微服务开发以及利用Netty搭建服务器等内容。
3031

被折叠的 条评论
为什么被折叠?



