class PersonFace(BasicPart): """PersonFace,人物人脸录入及比对模块 Arguments: BasicPart {[type]} -- [description] """ def __init__(self, threshold = None, logfile = None, picShow = False, isShow = False): ''' threshold: 人脸大小阈值 logfile: 日志文件路径 isShow: 显示图片处理过程 ''' BasicPart.__init__(self, logfile=logfile, isShow=isShow) self.picShow = picShow from DBHandler import DBHandler self.handler = DBHandler() self.initFR() # 缓存 self.dbcache = {} # self.initFI() def initFI(self): """初始化索引模块 """ from FeatureIndex import FeatureIndex prefixs = ['Person'] self.fi = FeatureIndex(index_prefixs=prefixs,isShow = self.isShow) def initFR(self): """初始化人脸特征提取模块 """ from FaceRecog import FaceRecog self.fr = FaceRecog(isShow = self.isShow, picShow = self.picShow) def read_config(self): """读配置文件 """ self.dir = {} self.maxdistance = self.config.getint('facerecog','max_distance') self.thresh = self.config.getint('facerecog','threshold') self.dir['faces'] = self.config.get('datadir','faces') self.dir['faces_feat'] = self.config.get('datadir','faces_feat') self.dir['faces_sample'] = self.config.get('datadir','faces_sample') def storePersonToDB(self): """将人物存到PersonInfo表,返回id """ self.person_ids = self.handler.addmanyPerson(self.person_names) def index_person(self, person_list = [], prefix="Person"): """对sample文件夹下所有人物人脸图片建立索引 或只建立某个人的索引 """ if len(person_list) == 0: self.person_names = os.listdir(self.dir['faces_sample']) else: self.person_names = person_list # 存数据库,获取id self.storePersonToDB() self.person_pic_feats = [] self.person_pic_ids = [] for index, person_name in enumerate(self.person_names): # 每一个人物对应一个文件夹 full_path = self.dir['faces_sample'] + '/' + person_name pic_list = os.listdir(full_path) num_faces = len(pic_list) for face_pic in pic_list: face_pic = full_path + '/' + face_pic pic_face_dic = self.fr.extract_image_face_feature(face_pic) feat = pic_face_dic['feats'][0] self.person_pic_feats.append(feat) self.person_pic_ids.append(self.person_ids[index]) # 建立索引 self.initFI() self.fi.create_person_index(self.person_pic_feats, self.person_pic_ids, prefix) def setFeatureIndex(self, fi): """设置FI对象,用于查询时,从外部导入已载入索引的索引对象 Arguments: fi {FeatureIndex} -- 索引检索对象 """ self.fi = fi def identify_pic_person(self, imagename): """确定图片中人物名字以及id Arguments: imagename {string} -- 图片名 Returns: personid, personname """ face_dic = self.fr.extract_image_face_feature(imagename) if len(face_dic['feats']) > 0: personid, personname = self.idenity(face_dic['feats'][0]) else: personid=-1 personname="无人物" return personid, personname # print(result) def idenity(self, facefeat): """确定人物身份,返回人物名及人物id Arguments: facefeat {data} -- 待确定的人脸特征 -1, unknown 未识别人物 """ # 首先进行query results, distance = self.fi.queryPerson(facefeat) # 若高于最远距离,则为未知人物,返回None,'' if distance[0] > self.maxdistance: personid = -1 personname = 'unknown' else: # 确定人物身份: # kmean max_count_id = pd.value_counts(results, sort=True).index[0] # 计算每个结果的得分 personid = int(max_count_id) # 首先查询缓存,若miss后再查询数据库 if personid in self.dbcache.keys(): personname = self.dbcache[personid] else: personname = self.handler.queryPersonById(personid)[0][1] self.dbcache[personid] = personname return personid, personname