【视觉多模态】基于视觉AI的人物轨迹生成方案
- 背景
- 步骤
- 小结
背景
基于 Yolo-World v2 把人物从视频每帧中提取出来并分别存储在某路径下。现在的下一步,应该是把这些截图全部转换为向量并存储到向量数据库。
步骤
- 下载SFace模型
https://github.com/opencv/opencv_zoo/blob/main/models/face_recognition_sface/face_recognition_sface_2021dec.onnx- 安装opencv-python 依赖,测试可用性
importcv2 print("OpenCV版本:", cv2.__version__)print("是否支持dnn模块:", hasattr(cv2,'dnn'))- 基础调用测试代码
importcv2importnumpy as np def sface_extract_face_vector(image_path, model_path,input_size=(112,112)):""" 利用SFace模型提取人脸图像的特征向量 :param image_path: 输入人脸图像路径 :param model_path: SFace模型(onnx格式)路径 :param input_size: SFace输入尺寸(固定112x112,不可修改) :return:512维人脸特征向量(归一化后)"""# 步骤1:读取并预处理图像(SFace强制要求,必须严格遵循)# 1.1 读取图像(彩色模式)img=cv2.imread(image_path)ifimg is None: raise FileNotFoundError(f"无法读取图像文件:{image_path}")# 1.2 转换色彩空间(BGR→RGB,SFace模型要求)img_rgb=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 1.3 调整图像尺寸(固定112x112,SFace输入尺寸)img_resized=cv2.resize(img_rgb, input_size)# 1.4 数据格式转换(HWC→CHW,并添加批次维度)img_transposed=np.transpose(img_resized,(2,0,1))# (H,W,C)→(C,H,W)img_batch=np.expand_dims(img_transposed,axis=0)# (C,H,W)→(1,C,H,W)# 1.5 归一化(像素值归一化到[-1, 1],SFace模型要求)img_normalized=(img_batch.astype(np.float32)-127.5)/127.5# 步骤2:加载SFace onnx模型net=cv2.dnn.readNetFromONNX(model_path)# 可选:启用GPU加速(若有NVIDIA GPU,需配置OpenCV GPU环境)# net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)# net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)# 步骤3:模型推理(前向传播,获取特征向量)net.setInput(img_normalized)face_vector=net.forward()# 输出形状:(1, 512)# 步骤4:向量归一化(提升后续相似度计算的准确性)face_vector_normalized=face_vector / np.linalg.norm(face_vector,axis=1,keepdims=True)# 步骤5:返回一维特征向量(去除批次维度)returnface_vector_normalized.squeeze()# ---------------------- 配置参数并运行 ----------------------if__name__=="__main__":# 配置路径(修改为你的实际路径)importos SFACE_MODEL_PATH="/data1/projs/SFace/opencv_zoo/face_recognition_sface_2021dec.onnx"path='/data1/datas/wildtrack_dataset/wildtrack_dataset/Wildtrack_dataset/Image_subsets/C1/cropped'forfileinos.listdir(path): TEST_IMAGE_PATH=f"{path}/{file}"try:# 提取人脸特征向量face_feature=sface_extract_face_vector(TEST_IMAGE_PATH, SFACE_MODEL_PATH)# 打印结果验证print("SFace特征向量形状:", face_feature.shape)# 应输出 (512,)print("SFace特征向量前10个值:", face_feature[:10])print("向量归一化验证(模长应≈1):", np.linalg.norm(face_feature))except Exception as e: print("运行报错:", str(e))结果:
024.8.0-linux-x64/bundled/libs/debugpy/adapter/../../debugpy/launcher41849-- /data1/projs/yolov5-botsort/test_only.py OpenCV版本:4.12.0 是否支持dnn模块: True SFace特征向量形状:(128,)SFace特征向量前10个值:[-0.041811070.105901390.045133310.013772150.0497637-0.03535534 -0.16844605 -0.079534460.00360839-0.02015602]向量归一化验证(模长应≈1):1.0SFace特征向量形状:(128,)[-0.008649510.137211070.00097885-0.00774572 -0.0306458 -0.01465974 -0.15866575 -0.06293750.090498960.017362320.0341635-0.13206565 -0.04685504 -0.059280860.04323329-0.035856850.11940002-0.003557990.05041823-0.01659128 -0.095046920.061995030.02595275-0.010231040.04494344-0.04678775 -0.006651940.062947180.05229411-0.11271915 -0.05184305 -0.03285127 -0.1269116 -0.18189423 -0.036520130.074977380.12063970.133915750.055842040.00342186-0.11525489 -0.1169667 -0.03108696 -0.10747405 -0.01156010.26701513-0.036781990.01830711-0.054812350.033669390.141028690.059063080.11707348-0.01611113 -0.101282090.06425073-0.044345770.226847960.07182860.10504609-0.10001983 -0.046612850.033695380.07690774-0.022769180.015273040.0209459-0.067221560.12785007-0.073309060.127180430.036501170.03357406-0.22308070.06874490.051670810.13399096-0.00556050.009251020.17704780.120136760.10237920.04011027-0.013265070.002124440.032370540.109193120.051502680.07991081-0.04595529 -0.05336874 -0.081588280.032809460.08914431-0.04767266 -0.09420003 -0.21350156 -0.049842370.125270650.017782810.046942-0.155373450.006912940.005221670.00649380.113883170.0553209-0.069932110.03343213-0.07741141 -0.04298204 -0.196524440.088440690.044994650.003223820.15364304-0.006026310.09509759-0.051170120.006598860.10149482-0.13059730.12939171-0.05865399 -0.0644947 -0.091725510.09984177-0.00866709]小结
SFace可用了,但有很多配套的内容需要补充。
(1)SFace 只针对人脸,并不包括人的身形、衣着等,因此,身形、衣着还是要另外的模型去辨别;
(2)SFace 只针对人脸,也因此,需要有前置的内容,先从图中检测到人脸,并进行切割后再传给SFace;
(3)细节上,为了更好发挥模型的效果,还有一个如下的流程:【意识上漏掉了一些逻辑,比如:对齐、标准化这两步】
原始图像 → 人脸检测(定位人脸框坐标) → 人脸裁剪(仅保留人脸区域) → 人脸对齐(可选,提升精度) → 标准化预处理(112x112/RGB/归一化) → SFace特征提取 → 有效512维人脸向量人脸检测:核心是定位人脸的位置和范围(输出人脸框的 x/y/w/h 坐标),解决 “图像里哪里有人脸” 的问题,过滤掉无脸 / 背影图像。
推荐模型:轻量场景用 OpenCV Haar 级联,高精度场景用 MTCNN/RetinaFace(能检测侧脸、小人脸,还能输出人脸关键点,为后续对齐做准备)。
人脸裁剪:根据检测到的人脸框坐标,从原始图像中精准切割出仅包含人脸的区域,剔除背景、身体、衣物等无关像素,让后续处理只聚焦人脸。
注意:裁剪时可适当扩大人脸框(比如向外扩展 10%),避免裁剪掉人脸边缘(如头发、下巴),保证人脸特征的完整性。
人脸对齐(可选但推荐):基于人脸检测输出的关键点(眼睛、鼻子、嘴巴),将人脸旋转、平移到标准正面姿态,解决人脸倾斜、侧脸导致的特征提取偏差。
这一步是提升 SFace 特征匹配精度的关键,比如同一人侧脸和正面的人脸,对齐后提取的向量相似度会大幅提升。
标准化预处理:将对齐后的人脸区域调整为 SFace 要求的112x112 固定尺寸,再完成 BGR→RGB、归一化到 [-1,1]、格式转换(HWC→CHW),满足模型输入格式要求。
所以,还需要进一步完善补充。