首页 > 解决方案 > 在 OpenCV C++ 中转换 Keras VGG16 预处理

问题描述

settings:
Tensorflow = 2.4.1, Keras = 2.4.3, Python = 3.7.9, OpenCV = 4.5.1

我使用 VGG16 的 Keras 基础模型进行迁移学习。我自己的模型架构开始于:

inputs = tf.keras.layers.Input(shape=(img_height, img_width, 3), name="input_layer")

x = tf.keras.applications.vgg16.preprocess_input(inputs)

x = tf.keras.applications.VGG16(weights=weights, include_top=include_top, input_shape=(img_height, img_width, 3))(x)

等等

之后我冻结我的模型并使用 freeze_optimize_inference.py。因此我的冻结层看起来像:

x

VGG16/tf.__operators__.getitem/strided_slice/stack

VGG16/tf.__operators__.getitem/strided_slice/stack_1

VGG16/tf.__operators__.getitem/strided_slice/stack_2

VGG16/tf.__operators__.getitem/strided_slice

VGG16/tf.nn.bias_add/BiasAdd/bias

VGG16/tf.nn.bias_add/BiasAdd

VGG16/vgg16/block1_conv1/Conv2D/ReadVariableOp/resource

VGG16/vgg16/block1_conv1/Conv2D/ReadVariableOp

等等

在 C++ 中,我使用 OpenCV 并阅读我的模型:

tensorflowNet = cv::dnn::readNetFromTensorflow("freeze_model_inference.pb");

这给了我错误:

OpenCV(4.5.1) C:\build\master_winpack-build-win64- 
vc14\opencv\modules\dnn\src\tensorflow\tf_importer.cpp:1527: error: (-213:The 
function/feature is not implemented) StridedSlice with stride -1 in function 
'cv::dnn::dnn4_v20201117::`anonymous-namespace'::TFImporter::populateNet'

empty model

对我来说,它说问题来自 vgg16.preprocess_input-layers。我可以创建一个没有这些层的模型,但是我遇到了一个问题“我怎样才能在 C++ 中准确地实现 VGG16 预处理?”

标签: pythonc++tensorflowopencvkeras

解决方案


根据tf.keras.applications.vgg16.preprocess_input文档[123.68, 116.779, 103.939],VGG 预处理只涉及从 RGB 转换为 BGR 并减去没有任何缩放的 ImageNet 平均值。

您可以通过简单地使用以下cv::dnn::blobFromImage功能来实现:

const double     SCALE_FACTOR = 1.0; # No scaling
const cv::Size   INPUT_SIZE   = cv::Size( 224, 224 ); # Adjust accordingly
const cv::Scalar RGB_MEAN     = cv::Scalar( 123.68, 116.779, 103.939 ); # RGB order
const bool       SWAP_RB      = false; # OpenCV images are already handled in BGR

cv::Mat blob = cv::dnn::blobFromImage( image, SCALE_FACTOR, INPUT_SIZE, RGB_MEAN, SWAP_RB );

推荐阅读