CenterFace项目中OpenCV为ONNX模型预处理输入数组的位置与方式
CenterFace人脸检测:OpenCV预处理定位与输入形状适配问题
一、预处理步骤的位置
你的代码里,所有图像预处理逻辑都集中在cv2.dnn.blobFromImage()这一行。这个函数是OpenCV DNN模块专门用来将原始图像转换成模型可识别的Blob格式的工具,它一次性完成了以下操作:
- 尺寸缩放:按照
size=(self.img_w_new, self.img_h_new)参数把输入图像缩放到指定的480×640大小 - 通道转换:通过
swapRB=True将OpenCV默认的BGR通道顺序转为RGB(和PyTorch常用输入格式一致) - 格式转换:把原始图像的HWC(高度、宽度、通道)格式转为模型需要的NCHW(批量数、通道数、高度、宽度)格式,也就是你打印出的
(1, 3, 480, 640) - 均值减法:这里
mean=(0,0,0)相当于没做均值减去操作
二、输入形状不符的原因与调整方案
你提到ONNX Runtime要求输入形状为(10, 3, 32, 32),这说明你用的两个推理环境(OpenCV DNN和ONNX Runtime)对应的ONNX模型可能是不同导出版本,或者原作者的OpenCV代码适配了动态输入尺寸(CenterFace本身支持任意输入尺寸)。要对齐输入要求,你可以这么改:
调整图像缩放尺寸
把blobFromImage里的size参数改成(32, 32),这样生成的Blob高度和宽度就会变成32×32:blob = cv2.dnn.blobFromImage(img, scalefactor=1.0, size=(32, 32), mean=(0, 0, 0), swapRB=True, crop=False)扩展批量数到10
默认blobFromImage生成的批量数是1(对应形状第一个维度的1),如果模型要求批量数为10,你可以通过numpy复制单张图像的Blob来实现:import numpy as np # 生成单张32×32的Blob blob = cv2.dnn.blobFromImage(img, scalefactor=1.0, size=(32, 32), mean=(0, 0, 0), swapRB=True, crop=False) # 复制成10个样本的批量输入 blob_batch = np.repeat(blob, 10, axis=0) # 设置模型输入 self.net.setInput(blob_batch)验证模型兼容性
注意:如果原OpenCV使用的ONNX模型是动态输入尺寸的,而ONNX Runtime的模型是固定批量和尺寸的,才需要做上述调整。如果是同一个模型,建议检查ONNX模型的输入节点配置,确认是否允许动态输入。
三、适配你的PyTorch使用习惯
如果你更熟悉PyTorch,可以把OpenCV的预处理换成PyTorch风格的实现,比如用torchvision.transforms:
from torchvision import transforms transform = transforms.Compose([ transforms.Resize((32, 32)), transforms.ToTensor(), transforms.Normalize(mean=[0,0,0], std=[1,1,1]) # 对应原代码的mean=(0,0,0) ]) # 假设img是PIL图像 input_tensor = transform(img).unsqueeze(0) # 得到(1,3,32,32) # 扩展批量到10 input_batch = input_tensor.repeat(10, 1, 1, 1) # 得到(10,3,32,32)
内容的提问来源于stack exchange,提问作者Xanta_Kross
相关产品推荐
相关产品推荐

