关于有关使用cv2加载caffe模型的问题!

有关使用cv2加载caffe模型的问题:
caffe模型的prototxt文件的第一个层为imagedata层,它的具体结构如下:

name: "AlexNet"
layers {
  name: "data"
  type: IMAGE_DATA
  top: "data"
  top: "label"
  transform_param {
    mirror: false
    crop_size: 227
  }
  image_data_param {
    source: "BS/databases06/pipa_features/ffaceregion_feat/train_shuffle.txt"
    batch_size: 1
    new_height: 227
    new_width: 227
  }
}

我想使用cv2加载该模型进行推理,已经有这个模型的prototx文件对应的caffemodel文件,可以成功加载。但根据imagedata层预处理图片,输入之后进行推理时仍然报错,请问应该怎么解决呢?代码为:

import cv2
import numpy as np

prototxt = 'model/alexnet_extraction.prototxt'
caffemodel = 'model/face.caffemodel'
imagelist = '1.jpg'
label_file = 'BS/databases06/pipa_features/ffaceregion_feat/train_shuffle.txt'

# 加载模型
net = cv2.dnn.readNetFromCaffe(prototxt, caffemodel)

# 读取图像和标签数据
with open(label_file, 'r') as f:
    lines = f.readlines()

for line in lines:
    line = line.strip().split(' ')
    image_path = line[0]
    label = int(line[1])

    # 读取图像
    image = cv2.imread('1.jpg')

    # 将图像像素值归一化到 [0, 1] 范围并减去均值
    image = image.astype(np.float32) / 255.0
    mean = np.array([104, 117, 123], dtype=np.float32)
    image -= mean

    # 构建 blob 对象
    blob = cv2.dnn.blobFromImage(image, scalefactor=1.0, size=(227, 227), mean=(104, 117, 123), swapRB=True, crop=False)
    # 设置输入 blob 到网络中
    net.setInput(blob)

    # 运行模型进行推理
    output = net.forward()

    # 处理输出结果
    # TODO: 根据实际需要进行后续处理

报错:

[ERROR:0@1.218] global net_impl.cpp:1164 cv::dnn::dnn4_v20221220::Net::Impl::getLayerShapesRecursively OPENCV/DNN: []:(_input): getMemoryShapes() throws exception. inputs=1 outputs=0/0 blobs=0
[ERROR:0@1.221] global net_impl.cpp:1167 cv::dnn::dnn4_v20221220::Net::Impl::getLayerShapesRecursively     input[0] = [ 1 3 227 227 ]
[ERROR:0@1.221] global net_impl.cpp:1177 cv::dnn::dnn4_v20221220::Net::Impl::getLayerShapesRecursively Exception message: OpenCV(4.7.0) d:\a\opencv-python\opencv-python\opencv\modules\dnn\src\layer_internals.hpp:309: error: (-215:Assertion failed) inputs.size() == requiredOutputs in function 'cv::dnn::dnn4_v20221220::detail::DataLayer::getMemoryShapes'

Traceback (most recent call last):
  File "E:/person_recognition/person_recogintion_personal_photo/main.py", line 36, in <module>
    output = net.forward()
cv2.error: OpenCV(4.7.0) d:\a\opencv-python\opencv-python\opencv\modules\dnn\src\layer_internals.hpp:309: error: (-215:Assertion failed) inputs.size() == requiredOutputs in function 'cv::dnn::dnn4_v20221220::detail::DataLayer::getMemoryShapes'


python调用caffe模型_使用caffe模型测试图片
可以借鉴下
https://blog.csdn.net/weixin_35875219/article/details/113517688

可能是由于图片预处理导致的。可以尝试在读取图像后,使用“cv2.cvtColor()”函数将图像从BGR颜色空间转换为RGB颜色空间,因为在Caffe模型中,RGB通常是默认的颜色空间。另外,layer的输入和输出形状也需要与图像的形状匹配。

输入数据形状不符合caffe模型网络层的要求,检查输入数据的维度或形状是否和网络的输入层对应,建议在代码中对输入数据进行reshape或者数据增强操作

从错误来看,指示了输入的数据形状大小和输出的形状大小不一致。检查下输入输出的形状大小是否一致,其次,有可能是配置的问题,将加载cafe配置的那一行修改为:

net = cv2.dnn.readNetFromTensorflow(model= "best_vgg16.pb",
    config=None)

如果不行,可以参考这个博主的解决方案,和你出现的问题一样:https://blog.csdn.net/weixin_46236212/article/details/122025815

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:

根据你提供的信息和代码,我发现你使用的是 OpenCV 自带的 dnn 模块加载 Caffe 模型进行推理。但是,你的 Caffe 模型的第一层是 ImageData 层,这意味着你需要对输入图像进行预处理,然后再将其输入到网络中进行推理。

然而,OpenCV 自带的 dnn 模块并不支持 ImageData 层的预处理。因此,你需要自己编写代码来实现 ImageData 层的预处理。

具体来说,你需要将 ImageData 层的预处理过程手动实现,包括:


1. 读取图像,并将其调整为合适的大小(根据 ImageData 层中的 new_heightnew_width 参数)。

2. 对图像进行归一化处理,并减去均值(根据 ImageData 层中的 transform_param 和 image_data_param 参数)。

3. 将处理后的图像作为输入 blob,传递给网络进行推理。

下面是一个参考示例代码,供你参考:

import cv2
import numpy as np

prototxt = 'model/alexnet_extraction.prototxt'
caffemodel = 'model/face.caffemodel'
imagelist = '1.jpg'
label_file = 'BS/databases06/pipa_features/ffaceregion_feat/train_shuffle.txt'

# 加载模型
net = cv2.dnn.readNetFromCaffe(prototxt, caffemodel)

# 读取图像和标签数据
with open(label_file, 'r') as f:
    lines = f.readlines()

for line in lines:
    line = line.strip().split(' ')
    image_path = line[0]
    label = int(line[1])

    # 读取图像
    image = cv2.imread('1.jpg')

    # 对图像进行预处理
    new_height = 227
    new_width = 227
    mean = np.array([104, 117, 123], dtype=np.float32)
    image = cv2.resize(image, (new_width, new_height))
    image = image.astype(np.float32) / 255.0
    image -= mean

    # 构建输入 blob
    blob = np.zeros((1, 3, new_height, new_width), dtype=np.float32)
    blob[0] = image.transpose((2, 0, 1))

    # 设置输入 blob 到网络中
    net.setInput(blob)

    # 运行模型进行推理
    output = net.forward()


   请注意,上述代码仅提供了一个基本的框架,如果你的模型中有其他特殊的层或操作,你可能需要根据实际情况进行修改。此外,如果你的模型中包含 BatchNorm 层,你还需要在推理时手动计算 BatchNorm 层的均值和方差,并将其应用到推理结果中。

最后,建议你将模型转换为 ONNX 格式,然后使用 OpenCV 自带的 dnn 模块加载 ONNX 模型进行推理。ONNX 模型的使用更加灵活和方便,也支持更多的网络层和操作,可以避免像 ImageData 层这样的问题。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢