def load_all_data(self): # 将以前标记的数据全部读入(直接读入的是特征), 用LSH Forest保存,方便计算距离 current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') try: all_pic_feature, all_label = self.load_train_data( self.all_pic_feature_data_folder) train_label = np.asarray(all_label) if len(all_pic_feature) == len( train_label) and len(train_label) > 0: start = time.time() self.lshf.fit(all_pic_feature, train_label) self.all_pic_feature = list(all_pic_feature) self.all_labels = list(train_label) end = time.time() self.load_time = end self.user_count = Counter(self.all_labels) log_file.write('\t'.join( map(str, [ self.user_count, 'fit all data time :', (end - start) ])) + '\n') log_file.close() except: traceback.print_exc() log_file.close() return
def extract_feature(face_array): ''' 先计算角度, 满足条件后再进行对齐和识别 :param face_array: RGB读入的数据(dtype=uint8) [0-255] :return: ''' start = time.time() current_day = get_current_day() current_time = get_current_time() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') blur_sign, blur_var = is_blur(face_array) if blur_sign: print 'blur_filter', blur_var feature_vector = np.reshape(np.asarray([0] * feature_dim), (1, feature_dim)) log_file.write('\t'.join(map(str, [current_time, 'blur', 'not_process', 'recognition_time :', (time.time() - start)])) + '\n') return feature_vector need_process = check_face_img(face_img=face_array) if not need_process: feature_vector = np.reshape(np.asarray([0] * feature_dim), (1, feature_dim)) log_file.write('\t'.join(map(str, [current_time, 'pose', 'not_process', 'recognition_time :', (time.time() - start)])) + '\n') return feature_vector # 自己检测对齐 face_align_array = align_face_rgb_array(face_array, bb=None) face_align_array = normalize_rgb_array(cv2.resize(face_align_array, (size, size))) feature_vector = get_Conv_FeatureMap([face_align_array, 0])[0].copy() log_file.write('\t'.join(map(str, [current_time, 'process', 'recognition_time :', (time.time() - start)])) + '\n') log_file.close() return feature_vector
def add_one_new_pic(self, pic_path, label): current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') try: # 读入数据时已经转换成需要的尺寸 result = self.extract_pic_feature(pic_path) if result == None: return False face_pic, pic_feature = result self.add_one_pic(pic_feature, label) pic_name = os.path.split(pic_path)[1] this_person_pic_folder = os.path.join(self.all_pic_data_folder, label) this_person_feature_folder = os.path.join( self.all_pic_feature_data_folder, label) if not os.path.exists(this_person_pic_folder): os.makedirs(this_person_pic_folder) if not os.path.exists(this_person_feature_folder): os.makedirs(this_person_feature_folder) # 直接存储图片对应的特征, 同时保存图片文件 this_pic_feature_name = os.path.join(this_person_feature_folder, pic_name + '.p') msgpack_numpy.dump(pic_feature, open(this_pic_feature_name, 'wb')) this_pic_face_name = os.path.join(this_person_pic_folder, pic_name + '.jpg') cv2.imwrite(this_pic_face_name, face_pic) log_file.write( '\t'.join(map(str, [pic_path, this_pic_face_name])) + '\n') return True except: traceback.print_exc() return False
def cal_nearest_sim(self, current_feature): nearest_sim_list = [] current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') try: length = len(self.nearest) for k in range(length): try: person_name, pre_feature = self.nearest[k] # 不在考虑时间, 只考虑图片的相似度 this_sim = pw.cosine_similarity( np.reshape(np.asarray(pre_feature), (1, len(pre_feature))), np.reshape(np.asarray(current_feature), (1, len(current_feature)))) nearest_sim_list.append( (this_sim, verification_model.predict(this_sim), person_name)) except: log_file.write('cal_nearest_sim error' + '\n') traceback.print_exc() continue return nearest_sim_list except: traceback.print_exc() return nearest_sim_list
def add_one_new_pic(self, pic_path, label): current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day+'.txt'), 'a') try: # 读入数据时已经转换成需要的尺寸 result = self.extract_pic_feature(pic_path) if result == None: return False face_pic, pic_feature = result self.add_one_pic(pic_feature, label) pic_name = os.path.split(pic_path)[1] this_person_pic_folder = os.path.join(self.all_pic_data_folder, label) this_person_feature_folder = os.path.join(self.all_pic_feature_data_folder, label) if not os.path.exists(this_person_pic_folder): os.makedirs(this_person_pic_folder) if not os.path.exists(this_person_feature_folder): os.makedirs(this_person_feature_folder) # 直接存储图片对应的特征, 同时保存图片文件 this_pic_feature_name = os.path.join(this_person_feature_folder, pic_name + '.p') msgpack_numpy.dump(pic_feature, open(this_pic_feature_name, 'wb')) this_pic_face_name = os.path.join(this_person_pic_folder, pic_name + '.jpg') cv2.imwrite(this_pic_face_name, face_pic) log_file.write('\t'.join(map(str, [pic_path, this_pic_face_name]))+'\n') return True except: traceback.print_exc() return False
def add_all_new_pic(self): ''' 将从上次加载数据到当前新增的文件都加载到LSH Forest(有可能是新增加一个人,还有可能是对已有的人增加新图片) 遍历文件夹(self.all_pic_data_folder),根据文件的时间判断是否需要加入该图片 用户新加入的图片先进行人脸检测, 如果能够检测到人脸,使用检测结果, 否则使用用户的原始图片 ''' current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') start = time.time() person_list = os.listdir(self.all_pic_data_folder) add_num = 0 for person in person_list: if self.must_same_str in person or self.maybe_same_str in person or self.new_person_str in person: continue person_path = os.path.join(self.all_pic_data_folder, person) if not os.path.isdir(person_path): continue pic_list = os.listdir(person_path) for pic in pic_list: pic_path = os.path.join(person_path, pic) last_modify_time = os.stat(pic_path).st_atime if last_modify_time > self.load_time: # 请求本地服务 request = { "label": person, "request_type": 'add', "one_pic_feature": pic_path } url = "http://127.0.0.1:%d/" % port result = image_request(request, url) try: add_flag = json.loads(result)["add"] if not add_flag: # 加载失败 log_file.write('\t'.join( map(str, ['no add file :', pic_path])) + '\n') else: add_num += 1 except: log_file.write( '\t'.join(map(str, ['no add file :', pic_path])) + '\n') traceback.print_exc() continue add_num += 1 end = time.time() if add_num > 0: self.load_time = end log_file.write( '\t'.join(map(str, ['self.load_time', self.load_time])) + '\n') log_file.write('\t'.join( map(str, [ 'add pic num :', add_num, 'Dynamic increase time :', (end - start) ])) + '\n') log_file.close() else: log_file.close()
def check_face_img(face_img): # pose_predict(姿势): [[pitch, yaw, roll]](Pitch: 俯仰; Yaw: 摇摆; Roll: 倾斜) ''' :param face_img: 人脸对应的矩阵 :param image_id: 图片id :return: 是否进行识别(False:不进行识别) ''' current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') face_img_str = base64.b64encode(msgpack_numpy.dumps(face_img)) request = { "request_type": 'check_pose', "face_img_str": face_img_str, "image_id": str(time.time()) } result = requests.post(angle_url, data=request) try: if result.status_code == 200: pose_predict = json.loads(result.content)["pose_predict"] if not pose_predict: # 加载失败 log_file.write('\t'.join(map(str, ['pose filter request'])) + '\n') log_file.close() return False else: pose_predict = msgpack_numpy.loads( base64.b64decode(pose_predict)) if pose_predict == None: log_file.write( '\t'.join(map(str, ['pose filter detect'])) + '\n') log_file.close() return False pitch, yaw, roll = pose_predict[0] if math.fabs(pitch) < pitch_threshold and math.fabs( yaw) < yaw_threshold and math.fabs( roll) < roll_threshold: log_file.write('\t'.join( map(str, ['pose not filter', str(pose_predict[0])])) + '\n') log_file.close() return True else: log_file.write('\t'.join( map(str, ['pose filter threshold', str(pose_predict[0])])) + '\n') log_file.close() return False else: return False except: traceback.print_exc() log_file.close() return False
def check_face_img(self, face_img, image_id): # 计算角度 ''' :param face_img: 人脸对应的矩阵 :param image_id: 图片id :return: 是否进行识别(False:不进行识别) ''' # 姿势检测 current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') face_img_str = base64.b64encode(msgpack_numpy.dumps(face_img)) request = { "request_type": 'check_pose', "face_img_str": face_img_str, "image_id": image_id, } url = "http://%s:%d/" % (check_ip, check_port) result = image_request(request, url) try: pose_predict = json.loads(result)["pose_predict"] if not pose_predict: # 加载失败 log_file.write( '\t'.join(map(str, [image_id, 'pose filter request'])) + '\n') log_file.close() return False else: pose_predict = msgpack_numpy.loads( base64.b64decode(pose_predict)) if pose_predict == None: log_file.write( '\t'.join(map(str, [image_id, 'pose filter detect'])) + '\n') log_file.close() return False pitch, yaw, roll = pose_predict[0] if math.fabs(pitch) < self.pitch_threshold and \ math.fabs(yaw) < self.yaw_threshold and \ math.fabs(roll) < self.roll_threshold: log_file.close() return True else: log_file.write('\t'.join( map(str, [image_id, 'pose filter threshold'])) + '\n') log_file.close() return False except: traceback.print_exc() log_file.close() return False
def add_all_new_pic(self): ''' 将从上次加载数据到当前新增的文件都加载到LSH Forest(有可能是新增加一个人,还有可能是对已有的人增加新图片) 遍历文件夹(self.all_pic_data_folder),根据文件的时间判断是否需要加入该图片 用户新加入的图片先进行人脸检测, 如果能够检测到人脸,使用检测结果, 否则使用用户的原始图片 ''' current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day+'.txt'), 'a') start = time.time() person_list = os.listdir(self.all_pic_data_folder) add_num = 0 for person in person_list: if self.must_same_str in person or self.maybe_same_str in person or self.new_person_str in person: continue person_path = os.path.join(self.all_pic_data_folder, person) if not os.path.isdir(person_path): continue pic_list = os.listdir(person_path) for pic in pic_list: pic_path = os.path.join(person_path, pic) last_modify_time = os.stat(pic_path).st_atime if last_modify_time > self.load_time: # 请求本地服务 request = { "label": person, "request_type": 'add', "one_pic_feature": pic_path } url = "http://127.0.0.1:%d/"%port result = image_request(request, url) try: add_flag = json.loads(result)["add"] if not add_flag:# 加载失败 log_file.write('\t'.join(map(str, ['no add file :', pic_path]))+'\n') else: add_num += 1 except: log_file.write('\t'.join(map(str, ['no add file :', pic_path]))+'\n') traceback.print_exc() continue add_num += 1 end = time.time() if add_num > 0: self.load_time = end log_file.write('\t'.join(map(str, ['self.load_time', self.load_time]))+'\n') log_file.write('\t'.join(map(str, ['add pic num :', add_num, 'Dynamic increase time :', (end - start)]))+'\n') log_file.close() else: log_file.close()
def extract_feature(face_array): ''' :param face_array: RGB读入的数据(dtype=uint8) [0-255] :return: ''' start = time.time() current_day = get_current_day() current_time = get_current_time() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') face_align_array = align_face_rgb_array(face_array, bb=dlib.rectangle(0, 0, face_array.shape[1], face_array.shape[0])) face_align_array = normalize_rgb_array(cv2.resize(face_align_array, (size, size))) feature_vector = get_Conv_FeatureMap([face_align_array, 0])[0].copy() log_file.write('\t'.join(map(str, [current_time, 'recognition_time :', (time.time() - start)])) + '\n') log_file.close() print (time.time() - start) return feature_vector
def post(self): start = time.time() current_day = get_current_day() current_time = get_current_time() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') pic_binary_data = self.request.body open('/tmp/face_recog_tmp/'+str(time.time())+'.jpg', 'wb').write(pic_binary_data) img_buffer = StringIO(pic_binary_data) img_array = np.array(Image.open(img_buffer)) img_array_bgr = cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR) print 'img_array_bgr.shape :', img_array_bgr.shape result = detect_recognize_face(img_array_bgr) self.write(result) end = time.time() log_file.write('\t'.join(map(str, [current_time, 'get_pic', 'all_time :', (end - start)])) + '\n') log_file.close()
def check_face_img(self, face_img, image_id): # 计算角度 ''' :param face_img: 人脸对应的矩阵 :param image_id: 图片id :return: 是否进行识别(False:不进行识别) ''' # 姿势检测 current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day+'.txt'), 'a') face_img_str = base64.b64encode(msgpack_numpy.dumps(face_img)) request = { "request_type": 'check_pose', "face_img_str": face_img_str, "image_id": image_id, } url = "http://%s:%d/" % (check_ip, check_port) result = image_request(request, url) try: pose_predict = json.loads(result)["pose_predict"] if not pose_predict: # 加载失败 log_file.write('\t'.join(map(str, [image_id, 'pose filter request'])) + '\n') log_file.close() return False else: pose_predict = msgpack_numpy.loads(base64.b64decode(pose_predict)) if pose_predict == None: log_file.write('\t'.join(map(str, [image_id, 'pose filter detect'])) + '\n') log_file.close() return False pitch, yaw, roll = pose_predict[0] if math.fabs(pitch) < self.pitch_threshold and \ math.fabs(yaw) < self.yaw_threshold and \ math.fabs(roll) < self.roll_threshold: log_file.close() return True else: log_file.write('\t'.join(map(str, [image_id, 'pose filter threshold'])) + '\n') log_file.close() return False except: traceback.print_exc() log_file.close() return False
def extract_feature(face_array): ''' 先计算角度, 满足条件后再进行对齐和识别 :param face_array: RGB读入的数据(dtype=uint8) [0-255] :return: ''' start = time.time() current_day = get_current_day() current_time = get_current_time() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') blur_sign, blur_var = is_blur(face_array) if blur_sign: print 'blur_filter', blur_var feature_vector = np.reshape(np.asarray([0] * feature_dim), (1, feature_dim)) log_file.write('\t'.join( map(str, [ current_time, 'blur', 'not_process', 'recognition_time :', (time.time() - start) ])) + '\n') return feature_vector need_process = check_face_img(face_img=face_array) if not need_process: feature_vector = np.reshape(np.asarray([0] * feature_dim), (1, feature_dim)) log_file.write('\t'.join( map(str, [ current_time, 'pose', 'not_process', 'recognition_time :', (time.time() - start) ])) + '\n') return feature_vector # 自己检测对齐 face_align_array = align_face_rgb_array(face_array, bb=None) face_align_array = normalize_rgb_array( cv2.resize(face_align_array, (size, size))) feature_vector = get_Conv_FeatureMap([face_align_array, 0])[0].copy() log_file.write('\t'.join( map(str, [ current_time, 'process', 'recognition_time :', (time.time() - start) ])) + '\n') log_file.close() return feature_vector
def check_face_img(face_img): # pose_predict(姿势): [[pitch, yaw, roll]](Pitch: 俯仰; Yaw: 摇摆; Roll: 倾斜) ''' :param face_img: 人脸对应的矩阵 :param image_id: 图片id :return: 是否进行识别(False:不进行识别) ''' current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') face_img_str = base64.b64encode(msgpack_numpy.dumps(face_img)) request = {"request_type": 'check_pose', "face_img_str": face_img_str, "image_id": str(time.time())} result = requests.post(angle_url, data=request) try: if result.status_code == 200: pose_predict = json.loads(result.content)["pose_predict"] if not pose_predict: # 加载失败 log_file.write('\t'.join(map(str, ['pose filter request'])) + '\n') log_file.close() return False else: pose_predict = msgpack_numpy.loads(base64.b64decode(pose_predict)) if pose_predict == None: log_file.write('\t'.join(map(str, ['pose filter detect'])) + '\n') log_file.close() return False pitch, yaw, roll = pose_predict[0] if math.fabs(pitch) < pitch_threshold and math.fabs(yaw) < yaw_threshold and math.fabs(roll) < roll_threshold: log_file.write('\t'.join(map(str, ['pose not filter', str(pose_predict[0])])) + '\n') log_file.close() return True else: log_file.write('\t'.join(map(str, ['pose filter threshold', str(pose_predict[0])])) + '\n') log_file.close() return False else: return False except: traceback.print_exc() log_file.close() return False
def find_current_new_person_id(self): current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day+'.txt'), 'a') old_person_id = [] person_list = os.listdir(self.all_pic_data_folder) for person in person_list: if person.startswith(self.new_person_str): tmp = person[len(self.new_person_str):].split('_') if len(tmp) > 0: this_id = int(tmp[0]) old_person_id.append(this_id) if len(old_person_id) == 0: current_new_person_id = 0 else: current_new_person_id = max(old_person_id) + 1 log_file.write('\t'.join(map(str, ['current_new_person_id :', current_new_person_id]))+'\n') log_file.close() return current_new_person_id
def load_all_data(self): # 将以前标记的数据全部读入,用LSH Forest保存,方便计算距离 current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day+'.txt'), 'a') train_data, train_label = load_train_data(self.all_pic_data_folder) if len(train_label) == 0: return pic_feature = self.extract_pic_feature(train_data) start = time.time() self.lshf.fit(pic_feature, train_label) self.all_pic_feature = list(pic_feature) self.all_labels = list(train_label) end = time.time() self.load_time = end self.user_count = Counter(self.all_labels) log_file.write('\t'.join(map(str, [self.user_count, 'fit all data time :', (end - start)]))+'\n') log_file.close()
def post(self): start = time.time() current_day = get_current_day() current_time = get_current_time() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') pic_binary_data = self.request.body open('/tmp/face_recog_tmp/' + str(time.time()) + '.jpg', 'wb').write(pic_binary_data) img_buffer = StringIO(pic_binary_data) img_array = np.array(Image.open(img_buffer)) img_array_bgr = cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR) print 'img_array_bgr.shape :', img_array_bgr.shape result = detect_recognize_face(img_array_bgr) self.write(result) end = time.time() log_file.write('\t'.join( map(str, [current_time, 'get_pic', 'all_time :', (end - start)])) + '\n') log_file.close()
def load_all_data(self): # 将以前标记的数据全部读入,用LSH Forest保存,方便计算距离 current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') train_data, train_label = load_train_data(self.all_pic_data_folder) if len(train_label) == 0: return pic_feature = self.extract_pic_feature(train_data) start = time.time() self.lshf.fit(pic_feature, train_label) self.all_pic_feature = list(pic_feature) self.all_labels = list(train_label) end = time.time() self.load_time = end self.user_count = Counter(self.all_labels) log_file.write('\t'.join( map(str, [self.user_count, 'fit all data time :', (end - start)])) + '\n') log_file.close()
def find_current_new_person_id(self): current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') old_person_id = [] person_list = os.listdir(self.all_pic_data_folder) for person in person_list: if person.startswith(self.new_person_str): tmp = person[len(self.new_person_str):].split('_') if len(tmp) > 0: this_id = int(tmp[0]) old_person_id.append(this_id) if len(old_person_id) == 0: current_new_person_id = 0 else: current_new_person_id = max(old_person_id) + 1 log_file.write('\t'.join( map(str, ['current_new_person_id :', current_new_person_id])) + '\n') log_file.close() return current_new_person_id
def load_all_data(self): # 将以前标记的数据全部读入(直接读入的是特征), 用LSH Forest保存,方便计算距离 current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day+'.txt'), 'a') try: all_pic_feature, all_label = self.load_train_data(self.all_pic_feature_data_folder) train_label = np.asarray(all_label) if len(all_pic_feature) == len(train_label) and len(train_label) > 0: start = time.time() self.lshf.fit(all_pic_feature, train_label) self.all_pic_feature = list(all_pic_feature) self.all_labels = list(train_label) end = time.time() self.load_time = end self.user_count = Counter(self.all_labels) log_file.write('\t'.join(map(str, [self.user_count, 'fit all data time :', (end - start)]))+'\n') log_file.close() except: traceback.print_exc() log_file.close() return
def cal_nearest_sim(self, current_feature): nearest_sim_list = [] current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day+'.txt'), 'a') try: length = len(self.nearest) for k in range(length): try: person_name, pre_feature = self.nearest[k] # 不在考虑时间, 只考虑图片的相似度 this_sim = pw.cosine_similarity(np.reshape(np.asarray(pre_feature), (1, len(pre_feature))), np.reshape(np.asarray(current_feature), (1, len(current_feature)))) nearest_sim_list.append((this_sim, verification_model.predict(this_sim), person_name)) except: log_file.write('cal_nearest_sim error'+'\n') traceback.print_exc() continue return nearest_sim_list except: traceback.print_exc() return nearest_sim_list
def recognize_online_cluster(self, image, image_id): ''' :param image: 将得到的图片进行识别,加入的LSH Forest,根据距离计算proba(不同的距离对应不同的准确率,根据已有的dist计算阈值); 和已经设定的阈值判断是不是一个新出现的人,确定是原来已有的人,还是不确定是原来已有的人 :return: ''' start = time.time() need_add = False need_save = False current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day+'.txt'), 'a') log_file.write('\t'.join(map(str, ["receive image", image_id, time.time()])) + '\n') feature_str = '' try: image = base64.decodestring(image) image = zlib.decompress(image) im = cv2.imdecode(np.fromstring(image, dtype=np.uint8), 1) log_file.write('\t'.join(map(str, ['shape :', im.shape[0], im.shape[1]])) + '\n') # 图片尺寸过滤 if im.shape[0] < size_threshold or im.shape[1] < size_threshold: log_file.write('\t'.join(map(str, ['stat recognize_time :', (time.time() - start), 'small_size'])) + '\n') log_file.close() return self.unknown, 1.0, feature_str, need_save # 清晰度过滤 blur_sign, blur_var = is_blur(cv2.resize(im, (96, 96))) if blur_sign: log_file.write('\t'.join(map(str, ['stat recognize_time :', (time.time() - start), 'blur_filter', blur_var])) + '\n') log_file.close() return self.unknown, 1.0, feature_str, need_save # 保存传过来的图片 # img_file = '/tmp/research_face/%s.jpg' %image_id time_slot = get_time_slot(image_id) if time_slot == None: time_slot = 'error' time_slot_dir = os.path.join(tmp_face_dir, time_slot) if not os.path.exists(time_slot_dir): os.makedirs(time_slot_dir) img_file = os.path.join(time_slot_dir, image_id+'.jpg') cv2.imwrite(img_file, im) except: traceback.print_exc() log_file.close() return self.unknown, 1.0, feature_str, need_save try: # 流程 : 找距离最近的图片 ; 计算prob ; 在线聚类 ; 加入LSH Forest result = self.extract_pic_feature(img_file) if result == None: log_file.write('\t'.join(map(str, ['stat not_find_face', 'time :', (time.time() - start)]))+'\n') log_file.close() return self.unknown, 1.0, feature_str, need_save face_pic, im_feature = result try: # nearest_sim_list的格式和dist_label_list的格式一样,这样可以将两个list合并,一起计算(这样不用考虑时间的因素) # 在识别出人名后将人名和feature放入到self.nearest nearest_sim_list = self.cal_nearest_sim(current_feature=im_feature) except: traceback.print_exc() nearest_sim_list = [] log_file.write('\t'.join(map(str, ['nearest_sim_list :', map(str, nearest_sim_list)])) + '\n') feature_str = base64.b64encode(msgpack_numpy.dumps(im_feature)) log_file.write('\t'.join(map(str, ['extract_feature_time :', (time.time() - start)]))+'\n') # 找距离最近的图片 --- 用LSH Forest 找出最近的10张图片,然后分别计算距离 tmp_list = self.find_k_neighbors_with_lsh(im_feature) nearest_sim_list.sort(key=lambda x: x[0], reverse=True) nearest_sim_list.extend(tmp_list) dist_label_list = nearest_sim_list[:] # 计算 log_file.write('\t'.join(map(str, ['dist_label_list :', map(str, dist_label_list)])) + '\n') if dist_label_list == None: this_id = self.must_be_not_same_id this_label = self.new_person_str + str(self.current_new_person_id) else: # 计算prob --- 根据距离计算prob this_id, this_label = self.evaluate_result(dist_label_list) # 不管概率, 都要将最新的一张图片加入到self.nearest self.nearest.append((this_label, im_feature)) log_file.write('\t'.join(map(str, ['self.nearest :', map(str, self.nearest)])) + '\n') # 在线聚类 --- 根据dist确定是重新增加一个人还是加入到已有的人中 if this_id == self.same_pic_id: need_add = False elif this_id == self.must_be_same_id: need_add = False need_save = True this_person_pic_folder = os.path.join(self.all_pic_data_folder, this_label+self.must_same_str) this_person_feature_folder = os.path.join(self.all_pic_feature_data_folder, this_label+self.must_same_str) elif this_id == self.must_be_not_same_id: this_label = self.new_person_str + str(self.current_new_person_id) self.current_new_person_id += 1 this_person_pic_folder = os.path.join(self.all_pic_data_folder, this_label) this_person_feature_folder = os.path.join(self.all_pic_feature_data_folder, this_label) need_add = True need_save = True elif this_id == self.maybe_same_id: this_person_pic_folder = os.path.join(self.all_pic_data_folder, this_label + self.maybe_same_str) this_person_feature_folder = os.path.join(self.all_pic_feature_data_folder, this_label + self.maybe_same_str) need_add = False # prob在灰度区域的不如入,其余情况加入 need_save = True else: log_file.write('\t'.join(map(str, ['error para :', this_id]))+'\n') if need_save: try: if not os.path.exists(this_person_pic_folder): os.makedirs(this_person_pic_folder) if not os.path.exists(this_person_feature_folder): os.makedirs(this_person_feature_folder) # 直接存储图片对应的特征, 同时保存图片文件 this_pic_feature_name = os.path.join(this_person_feature_folder, image_id+'.p') msgpack_numpy.dump(im_feature, open(this_pic_feature_name, 'wb')) this_pic_face_name = os.path.join(this_person_pic_folder, image_id+'.jpg') cv2.imwrite(this_pic_face_name, face_pic) except: traceback.print_exc() return self.unknown, 1.0, feature_str, False # 加入LSH Forest --- partial_fit if need_add: self.add_one_pic(im_feature, this_label) # 根据label和image_id可以存生成文件名,确定是否要存储文件[可以选择在服务器和本地同时存储] if this_id == self.same_pic_id or this_id == self.must_be_not_same_id or this_id == self.must_be_same_id: end = time.time() log_file.write('\t'.join(map(str, ['stat recognize_time :',(end - start), 'this_id :', self.trans_dic.get(this_id)]))+'\n') log_file.close() need_save = True return this_label.replace(self.must_same_str, ''), str(dist_label_list[0][0]), str(feature_str), str(need_save) else: # 灰度区域,不显示人名 end = time.time() log_file.write('\t'.join(map(str, ['stat gray_area :',(end - start)]))+'\n') log_file.close() return self.unknown, str(dist_label_list[0][0]), str(feature_str), str(False) except: traceback.print_exc() log_file.close() return self.unknown, str(100.0), str(feature_str), str(False)
def recognize_online_cluster(self, image, image_id): ''' :param image: 将得到的图片进行识别,加入的LSH Forest,根据距离计算proba(不同的距离对应不同的准确率,根据已有的dist计算阈值); 和已经设定的阈值判断是不是一个新出现的人,确定是原来已有的人,还是不确定是原来已有的人 :return: ''' start = time.time() need_add = False need_save = False current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') log_file.write( '\t'.join(map(str, ["receive image", image_id, time.time()])) + '\n') feature_str = '' try: image = base64.decodestring(image) image = zlib.decompress(image) im = cv2.imdecode(np.fromstring(image, dtype=np.uint8), 1) log_file.write( '\t'.join(map(str, ['shape :', im.shape[0], im.shape[1]])) + '\n') # 图片尺寸过滤 if im.shape[0] < size_threshold or im.shape[1] < size_threshold: log_file.write('\t'.join( map(str, [ 'stat recognize_time :', (time.time() - start), 'small_size' ])) + '\n') log_file.close() return self.unknown, 1.0, feature_str, need_save # 清晰度过滤 blur_sign, blur_var = is_blur(cv2.resize(im, (96, 96))) if blur_sign: log_file.write('\t'.join( map(str, [ 'stat recognize_time :', (time.time() - start), 'blur_filter', blur_var ])) + '\n') log_file.close() return self.unknown, 1.0, feature_str, need_save # 保存传过来的图片 # img_file = '/tmp/research_face/%s.jpg' %image_id time_slot = get_time_slot(image_id) if time_slot == None: time_slot = 'error' time_slot_dir = os.path.join(tmp_face_dir, time_slot) if not os.path.exists(time_slot_dir): os.makedirs(time_slot_dir) img_file = os.path.join(time_slot_dir, image_id + '.jpg') cv2.imwrite(img_file, im) except: traceback.print_exc() log_file.close() return self.unknown, 1.0, feature_str, need_save try: # 流程 : 找距离最近的图片 ; 计算prob ; 在线聚类 ; 加入LSH Forest result = self.extract_pic_feature(img_file) if result == None: log_file.write('\t'.join( map(str, [ 'stat not_find_face', 'time :', (time.time() - start) ])) + '\n') log_file.close() return self.unknown, 1.0, feature_str, need_save face_pic, im_feature = result try: # nearest_sim_list的格式和dist_label_list的格式一样,这样可以将两个list合并,一起计算(这样不用考虑时间的因素) # 在识别出人名后将人名和feature放入到self.nearest nearest_sim_list = self.cal_nearest_sim( current_feature=im_feature) except: traceback.print_exc() nearest_sim_list = [] log_file.write('\t'.join( map(str, ['nearest_sim_list :', map(str, nearest_sim_list)])) + '\n') feature_str = base64.b64encode(msgpack_numpy.dumps(im_feature)) log_file.write('\t'.join( map(str, ['extract_feature_time :', (time.time() - start)])) + '\n') # 找距离最近的图片 --- 用LSH Forest 找出最近的10张图片,然后分别计算距离 tmp_list = self.find_k_neighbors_with_lsh(im_feature) nearest_sim_list.sort(key=lambda x: x[0], reverse=True) nearest_sim_list.extend(tmp_list) dist_label_list = nearest_sim_list[:] # 计算 log_file.write('\t'.join( map(str, ['dist_label_list :', map(str, dist_label_list)])) + '\n') if dist_label_list == None: this_id = self.must_be_not_same_id this_label = self.new_person_str + str( self.current_new_person_id) else: # 计算prob --- 根据距离计算prob this_id, this_label = self.evaluate_result(dist_label_list) # 不管概率, 都要将最新的一张图片加入到self.nearest self.nearest.append((this_label, im_feature)) log_file.write( '\t'.join(map(str, ['self.nearest :', map(str, self.nearest)])) + '\n') # 在线聚类 --- 根据dist确定是重新增加一个人还是加入到已有的人中 if this_id == self.same_pic_id: need_add = False elif this_id == self.must_be_same_id: need_add = False need_save = True this_person_pic_folder = os.path.join( self.all_pic_data_folder, this_label + self.must_same_str) this_person_feature_folder = os.path.join( self.all_pic_feature_data_folder, this_label + self.must_same_str) elif this_id == self.must_be_not_same_id: this_label = self.new_person_str + str( self.current_new_person_id) self.current_new_person_id += 1 this_person_pic_folder = os.path.join(self.all_pic_data_folder, this_label) this_person_feature_folder = os.path.join( self.all_pic_feature_data_folder, this_label) need_add = True need_save = True elif this_id == self.maybe_same_id: this_person_pic_folder = os.path.join( self.all_pic_data_folder, this_label + self.maybe_same_str) this_person_feature_folder = os.path.join( self.all_pic_feature_data_folder, this_label + self.maybe_same_str) need_add = False # prob在灰度区域的不如入,其余情况加入 need_save = True else: log_file.write('\t'.join(map(str, ['error para :', this_id])) + '\n') if need_save: try: if not os.path.exists(this_person_pic_folder): os.makedirs(this_person_pic_folder) if not os.path.exists(this_person_feature_folder): os.makedirs(this_person_feature_folder) # 直接存储图片对应的特征, 同时保存图片文件 this_pic_feature_name = os.path.join( this_person_feature_folder, image_id + '.p') msgpack_numpy.dump(im_feature, open(this_pic_feature_name, 'wb')) this_pic_face_name = os.path.join(this_person_pic_folder, image_id + '.jpg') cv2.imwrite(this_pic_face_name, face_pic) except: traceback.print_exc() return self.unknown, 1.0, feature_str, False # 加入LSH Forest --- partial_fit if need_add: self.add_one_pic(im_feature, this_label) # 根据label和image_id可以存生成文件名,确定是否要存储文件[可以选择在服务器和本地同时存储] if this_id == self.same_pic_id or this_id == self.must_be_not_same_id or this_id == self.must_be_same_id: end = time.time() log_file.write('\t'.join( map(str, [ 'stat recognize_time :', (end - start), 'this_id :', self.trans_dic.get(this_id) ])) + '\n') log_file.close() need_save = True return this_label.replace(self.must_same_str, ''), str( dist_label_list[0][0]), str(feature_str), str(need_save) else: # 灰度区域,不显示人名 end = time.time() log_file.write( '\t'.join(map(str, ['stat gray_area :', (end - start)])) + '\n') log_file.close() return self.unknown, str( dist_label_list[0][0]), str(feature_str), str(False) except: traceback.print_exc() log_file.close() return self.unknown, str(100.0), str(feature_str), str(False)
def recognize_online_cluster(self, image, image_id): ''' :param image: 将得到的图片进行识别,加入的LSH Forest,根据距离计算proba(不同的距离对应不同的准确率,根据已有的dist计算阈值); 和已经设定的阈值判断是不是一个新出现的人,确定是原来已有的人,还是不确定是原来已有的人 # 增加统计的功能, 方便以后计算过滤原因和比例, 以及识别比例(same, not_same, maybe_same) :return: ''' start = time.time() need_add = False has_save_num = 0 current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day + '.txt'), 'a') log_file.write( '\t'.join(map(str, ["receive image", image_id, time.time()])) + '\n') try: image = base64.decodestring(image) image = zlib.decompress(image) im = cv2.imdecode(np.fromstring(image, dtype=np.uint8), 1) time_slot = get_time_slot(image_id) if time_slot == None: time_slot = 'error' time_slot_dir = os.path.join(tmp_face_dir, time_slot) if not os.path.exists(time_slot_dir): os.makedirs(time_slot_dir) tmp_pic_path = os.path.join(time_slot_dir, image_id + '.jpg') cv2.imwrite(tmp_pic_path, im) blur_result = is_blur(im) blur_sign, blur_var = blur_result if blur_sign: log_file.write('\t'.join( map(str, ['stat', 'blur_filter', blur_var, image_id])) + '\n') log_file.close() return self.unknown, 1.0, self.has_save_pic_feature, need_add align_face_img = align_face(tmp_pic_path) if align_face_img == None: log_file.write('\t'.join( map(str, ['stat', 'detect_filter', blur_var, image_id])) + '\n') log_file.close() return self.unknown, 1.0, self.has_save_pic_feature, need_add else: # 使用重新检测并对对齐的人脸进行识别 im = align_face_img # 对检测到的人脸重新进行模糊检测 blur_result = is_blur(im) blur_sign, blur_var = blur_result if blur_sign: log_file.write('\t'.join( map(str, ['stat', 'blur_filter', blur_var, image_id])) + '\n') log_file.close() return self.unknown, 1.0, self.has_save_pic_feature, need_add need_process = self.check_face_img(im, image_id) if not need_process: log_file.write('\t'.join( map(str, ['stat', 'pose_filter', blur_var, image_id])) + '\n') log_file.close() return self.unknown, 1.0, self.has_save_pic_feature, need_add im = cv2.resize(im, (PIC_SHAPE[1], PIC_SHAPE[2]), interpolation=cv2.INTER_LINEAR) im = im[:, :, ::-1] * 1.0 im = im - avg im = im.transpose((2, 0, 1)) im = im[None, :] except: traceback.print_exc() return self.unknown, 1.0, self.has_save_pic_feature, need_add try: # 流程 : 找距离最近的图片 ; 计算prob ; 在线聚类 ; 加入LSH Forest im_feature = extract_feature_from_numpy(im) try: # nearest_sim_list的格式和dist_label_list的格式一样,这样可以将两个list合并,一起计算(这样不用考虑时间的因素) # 在识别出人名后将人名和feature放入到self.nearest nearest_sim_list = self.cal_nearest_sim( current_feature=im_feature) except: traceback.print_exc() nearest_sim_list = [] log_file.write('\t'.join( map(str, ['nearest_sim_list :', map(str, nearest_sim_list)])) + '\n') # 找距离最近的图片 --- 用LSH Forest 找出最近的10张图片,然后分别计算距离 dist_label_list = self.find_k_neighbors_with_lsh(im_feature) dist_label_list.extend(nearest_sim_list) dist_label_list = self.filter_result(dist_label_list) dist_label_list.sort(key=lambda x: x[0], reverse=True) # 计算 if dist_label_list == None: this_id = self.must_be_not_same_id this_label = self.new_person_str + str( self.current_new_person_id) else: # 计算prob --- 根据距离计算prob this_id, this_label = self.evaluate_result(dist_label_list) # 在线聚类 --- 根据dist确定是重新增加一个人还是加入到已有的人中 log_file.write('\t'.join( map(str, ['stat', 'recognize_id', blur_var, this_id])) + '\n') if dist_label_list != None and len(dist_label_list) > 0: log_file.write('\t'.join( map(str, ['dist_label_list :', map(str, dist_label_list)])) + '\n') need_save = False if this_id == self.same_pic_id: need_add = False elif this_id == self.must_be_same_id: need_add = False need_save = True this_person_folder = os.path.join( self.all_pic_data_folder, this_label + self.must_same_str) elif this_id == self.must_be_not_same_id: this_label = self.new_person_str + str( self.current_new_person_id) self.current_new_person_id += 1 this_person_folder = os.path.join(self.all_pic_data_folder, this_label) need_add = True need_save = True elif this_id == self.maybe_same_id: this_person_folder = os.path.join( self.all_pic_data_folder, this_label + self.maybe_same_str) need_add = False # prob在灰度区域的不如入,其余情况加入 need_save = True else: log_file.write('\t'.join(map(str, ['error para :', this_id])) + '\n') if need_save: try: if not os.path.exists(this_person_folder): os.makedirs(this_person_folder) os.chmod(this_person_folder, stat.S_IRWXG + stat.S_IRWXO + stat.S_IRWXU) this_pic_name = os.path.join(this_person_folder, image_id + '.png') imsave(this_pic_name, np.transpose(im[0], (1, 2, 0))) except: traceback.print_exc() return self.unknown, 1.0, has_save_num, False # 加入LSH Forest --- partial_fit if need_add: self.add_one_pic(im_feature, this_label) has_save_num += 1 # 根据label和image_id可以存生成文件名,确定是否要存储文件[可以选择在服务器和本地同时存储] if this_id == self.same_pic_id or this_id == self.must_be_not_same_id or this_id == self.must_be_same_id: end = time.time() log_file.write('\t'.join( map(str, [ 'stat recognize_time :', (end - start), 'this_id :', self.trans_dic.get(this_id) ])) + '\n') log_file.close() return this_label.replace(self.must_same_str, ''), \ str(dist_label_list[0][0]), str(has_save_num), str(need_add) else: # 灰度区域,不显示人名 end = time.time() log_file.write('\t'.join( map(str, ['gray area recog time :', (end - start)])) + '\n') log_file.close() # return this_label.replace(self.maybe_same_str, ''), \ # str(dist_label_list[0][0]), str(has_save_num), str(need_add) return self.unknown, str( dist_label_list[0][0]), str(has_save_num), str(need_add) except: traceback.print_exc() log_file.close() return self.unknown, str(100.0), str(has_save_num), str(False)
def recognize_online_cluster(self, image, image_id): ''' :param image: 将得到的图片进行识别,加入的LSH Forest,根据距离计算proba(不同的距离对应不同的准确率,根据已有的dist计算阈值); 和已经设定的阈值判断是不是一个新出现的人,确定是原来已有的人,还是不确定是原来已有的人 # 增加统计的功能, 方便以后计算过滤原因和比例, 以及识别比例(same, not_same, maybe_same) :return: ''' start = time.time() need_add = False has_save_num = 0 current_day = get_current_day() log_file = open(os.path.join(log_dir, current_day+'.txt'), 'a') log_file.write('\t'.join(map(str, ["receive image", image_id, time.time()])) + '\n') try: image = base64.decodestring(image) image = zlib.decompress(image) im = cv2.imdecode(np.fromstring(image, dtype=np.uint8), 1) time_slot = get_time_slot(image_id) if time_slot == None: time_slot = 'error' time_slot_dir = os.path.join(tmp_face_dir, time_slot) if not os.path.exists(time_slot_dir): os.makedirs(time_slot_dir) tmp_pic_path = os.path.join(time_slot_dir, image_id+'.jpg') cv2.imwrite(tmp_pic_path, im) blur_result = is_blur(im) blur_sign, blur_var = blur_result if blur_sign: log_file.write('\t'.join(map(str, ['stat', 'blur_filter', blur_var, image_id]))+'\n') log_file.close() return self.unknown, 1.0, self.has_save_pic_feature, need_add align_face_img = align_face(tmp_pic_path) if align_face_img == None: log_file.write('\t'.join(map(str, ['stat', 'detect_filter', blur_var, image_id])) + '\n') log_file.close() return self.unknown, 1.0, self.has_save_pic_feature, need_add else: # 使用重新检测并对对齐的人脸进行识别 im = align_face_img # 对检测到的人脸重新进行模糊检测 blur_result = is_blur(im) blur_sign, blur_var = blur_result if blur_sign: log_file.write('\t'.join(map(str, ['stat', 'blur_filter', blur_var, image_id]))+'\n') log_file.close() return self.unknown, 1.0, self.has_save_pic_feature, need_add need_process = self.check_face_img(im, image_id) if not need_process: log_file.write('\t'.join(map(str, ['stat', 'pose_filter', blur_var, image_id])) + '\n') log_file.close() return self.unknown, 1.0, self.has_save_pic_feature, need_add im = cv2.resize(im, (PIC_SHAPE[1], PIC_SHAPE[2]), interpolation=cv2.INTER_LINEAR) im = im[:, :, ::-1]*1.0 im = im - avg im = im.transpose((2, 0, 1)) im = im[None, :] except: traceback.print_exc() return self.unknown, 1.0, self.has_save_pic_feature, need_add try: # 流程 : 找距离最近的图片 ; 计算prob ; 在线聚类 ; 加入LSH Forest im_feature = extract_feature_from_numpy(im) try: # nearest_sim_list的格式和dist_label_list的格式一样,这样可以将两个list合并,一起计算(这样不用考虑时间的因素) # 在识别出人名后将人名和feature放入到self.nearest nearest_sim_list = self.cal_nearest_sim(current_feature=im_feature) except: traceback.print_exc() nearest_sim_list = [] log_file.write('\t'.join(map(str, ['nearest_sim_list :', map(str, nearest_sim_list)])) + '\n') # 找距离最近的图片 --- 用LSH Forest 找出最近的10张图片,然后分别计算距离 dist_label_list = self.find_k_neighbors_with_lsh(im_feature) dist_label_list.extend(nearest_sim_list) dist_label_list = self.filter_result(dist_label_list) dist_label_list.sort(key=lambda x: x[0], reverse=True) # 计算 if dist_label_list == None: this_id = self.must_be_not_same_id this_label = self.new_person_str + str(self.current_new_person_id) else: # 计算prob --- 根据距离计算prob this_id, this_label = self.evaluate_result(dist_label_list) # 在线聚类 --- 根据dist确定是重新增加一个人还是加入到已有的人中 log_file.write('\t'.join(map(str, ['stat', 'recognize_id', blur_var, this_id])) + '\n') if dist_label_list != None and len(dist_label_list) > 0: log_file.write('\t'.join(map(str, ['dist_label_list :', map(str, dist_label_list)])) + '\n') need_save = False if this_id == self.same_pic_id: need_add = False elif this_id == self.must_be_same_id: need_add = False need_save = True this_person_folder = os.path.join(self.all_pic_data_folder, this_label+self.must_same_str) elif this_id == self.must_be_not_same_id: this_label = self.new_person_str + str(self.current_new_person_id) self.current_new_person_id += 1 this_person_folder = os.path.join(self.all_pic_data_folder, this_label) need_add = True need_save = True elif this_id == self.maybe_same_id: this_person_folder = os.path.join(self.all_pic_data_folder, this_label+self.maybe_same_str) need_add = False # prob在灰度区域的不如入,其余情况加入 need_save = True else: log_file.write('\t'.join(map(str, ['error para :', this_id])) + '\n') if need_save: try: if not os.path.exists(this_person_folder): os.makedirs(this_person_folder) os.chmod(this_person_folder, stat.S_IRWXG + stat.S_IRWXO + stat.S_IRWXU) this_pic_name = os.path.join(this_person_folder, image_id+'.png') imsave(this_pic_name, np.transpose(im[0], (1, 2, 0))) except: traceback.print_exc() return self.unknown, 1.0, has_save_num, False # 加入LSH Forest --- partial_fit if need_add: self.add_one_pic(im_feature, this_label) has_save_num += 1 # 根据label和image_id可以存生成文件名,确定是否要存储文件[可以选择在服务器和本地同时存储] if this_id == self.same_pic_id or this_id == self.must_be_not_same_id or this_id == self.must_be_same_id: end = time.time() log_file.write('\t'.join(map(str, ['stat recognize_time :', (end - start), 'this_id :', self.trans_dic.get(this_id)])) + '\n') log_file.close() return this_label.replace(self.must_same_str, ''), \ str(dist_label_list[0][0]), str(has_save_num), str(need_add) else: # 灰度区域,不显示人名 end = time.time() log_file.write('\t'.join(map(str, ['gray area recog time :',(end - start)])) + '\n') log_file.close() # return this_label.replace(self.maybe_same_str, ''), \ # str(dist_label_list[0][0]), str(has_save_num), str(need_add) return self.unknown, str(dist_label_list[0][0]), str(has_save_num), str(need_add) except: traceback.print_exc() log_file.close() return self.unknown, str(100.0), str(has_save_num), str(False)