人脸编码存储至数据库/文件后,调用face_recognition.compare_faces报错求助
问题分析与解决方案
报错根源
从报错信息 numpy.core._exceptions._UFuncNoLoopError: ufunc 'subtract' did not contain a loop with signature matching types (dtype('float64'), dtype('<U1558')) -> None 可以明确:
你从文件/MongoDB取出的人脸编码x是字符串类型(dtype('<U1558')表示Unicode字符串),但新生成的编码encode是float64类型的numpy数组,两者无法执行减法运算(face_distance内部会做数组减法),导致报错。
核心解决步骤
1. 修正人脸编码的存储逻辑
存储时必须保存原始的numpy数组(或可还原为数组的结构),不能将编码转成字符串存储:
# 正确的存储示例(pickle方式) import pickle import face_recognition # 生成并保存编码 image = face_recognition.load_image_file("IMAGES/UTKARSH RAI.jpg") encode = face_recognition.face_encodings(image)[0] data = {"enc": [encode]} with open("Encodings/encodings.pickle", "wb") as f: pickle.dump(data, f)
如果用MongoDB存储:
- 存储时将numpy数组转为列表:
encode.tolist() - 读取后再转回numpy数组:
np.array(读取到的列表, dtype=np.float64)
2. 修正读取代码的类型转换
在读取后强制将x转为float64类型的numpy数组,确保和新编码类型匹配:
import pickle import cv2,face_recognition import numpy as np enc=[] with open("Encodings/encodings.pickle", "rb") as openfile: x = pickle.load(openfile) x = x["enc"][0] # 强制转换为float64数组,确保类型正确 x = np.array(x, dtype=np.float64) # 可以打印类型确认:print(type(x), x.dtype) 应输出 <class 'numpy.ndarray'> float64 image = cv2.imread("IMAGES/UTKARSH RAI.jpg") image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) encode = face_recognition.face_encodings(image)[0] enc.append(encode) com = face_recognition.compare_faces(enc,x) dis = face_recognition.face_distance(enc,x) print(dis)
关键注意事项
- 存储人脸编码时,绝对不要将numpy数组转为字符串(比如用
str(encode)),否则读取后无法还原为可运算的数值数组。 - 若使用MongoDB,避免直接存储numpy数组(MongoDB不原生支持),转成列表后存储是稳妥方案。
内容的提问来源于stack exchange,提问作者user7294879
相关产品推荐
相关产品推荐

