要提取每一帧的特征,可以使用 OpenCV 库中的 cv2.dnn.readNetFromCaffe()
函数加载一个已经训练好的深度学习模型,并用它对每一帧进行推断,得到该帧的特征向量。
下面是代码示例:
import cv2
import numpy as np
# 加载预训练模型和配置文件
model = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'res10_300x300_ssd_iter_140000_fp16.caffemodel')
# 读取视频
cap = cv2.VideoCapture('E:/HDM05-Parser/14_04.avi')
# 定义帧数和每秒显示帧数
fps = cap.get(cv2.CAP_PROP_FPS)
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print("FPS: ", fps, " Frame count: ", frame_count)
# 定义特征向量矩阵,维度为 (2048,x),x 表示总共有多少个图像帧数
features_matrix = np.zeros((2048, frame_count), dtype=np.float32)
# 遍历所有帧并提取特征
for i in range(frame_count):
# 读取当前帧并将其转换为 blob 格式
ret, frame = cap.read()
if not ret:
break
blob = cv2.dnn.blobFromImage(frame, 1.0, (224, 224), (104.0, 177.0, 123.0))
# 使用模型进行推断,并将结果保存到特征向量矩阵中
model.setInput(blob)
features = model.forward()
features_matrix[:, i] = features.flatten()
# 释放资源
cap.release()
# 输出特征向量矩阵的形状信息
print(features_matrix.shape) # (2048,x),其中 x 表示总共有多少个图像帧数
在这里,我们使用了 OpenCV 中的 cv2.dnn.blobFromImage()
函数将每一帧转换为模型需要的 blob 格式。同时,我们也可以通过修改函数参数来调整输入图像的尺寸和颜色空间等属性。
然后,我们使用 model.setInput()
将当前帧作为模型的输入,并使用 model.forward()
进行推断。最后,将得到的特征向量保存到特征向量矩阵中。
值得注意的是,在上述代码中,我们没有指定要提取哪个层级(如全连接层)的输出作为特征向量。这是因为在这种情况下,默认情况下会返回最后一个卷积层(ResNet50 的最后一个卷积层具有 2048 个通道),其输出已经被平坦化成了一个长度为 2048 的一维数组。