【问题标题】:Tensorflow 2 Object Detection with OpenCV C++使用 OpenCV C++ 的 Tensorflow 2 对象检测
【发布时间】:2021-01-18 03:39:04
【问题描述】:

我已经使用 Tensorflow 2 对象检测 API 训练了 SSD ResNet V1 模型。然后我想在 C++ 代码中将此模型与 OpenCV 一起使用。

首先,经过培训,我有三个文件:

  • 检查点
  • ckpt-101.data-00000-of-00001
  • ckpt-101.index

请注意,我没有 .meta 文件,因为它不是生成的。

然后我使用对象检测 API 中的 exporter_main_v2.py 脚本从这些文件中创建了 SavedModel:

python3 exporter_main_v2.py input_type=image_tensor --pipeline_config_path /path/to/pipeline.config --trained_checkpoint_dir=/path/to/checkouts --output_directory=/path/to/output/directory

运行此脚本后,我得到了 saved_model.pb

我尝试以这种方式在 OpenCV 中使用此文件:

cv::dnn::Net net = cv::dnn::readNetFromTensorflow("/path/to/saved_model.pb");

但我收到以下错误:

OpenCV(4.2.0) /home/andrew/opencv/modules/dnn/src/tensorflow/tf_io.cpp:42: error: (-2:Unspecified error) FAILED: ReadProtoFromBinaryFile(param_file, param). Failed to parse GraphDef file: /home/andrew/Documents/tensorflow_detection/workspace/pb_model/saved_model/saved_model.pb in function 'ReadTFNetParamsFromBinaryFileOrDie'

然后我尝试冻结 saved_model.pb。但是,据我了解,在 TF2.x 中这是不可能的,因为 TF2.x 不支持 Sessions 和 Graphs。我也没有 .pbtxt 文件。

我的问题:是否可以在 OpenCV C++ 中使用使用 TF2 对象检测 API 训练的模型?

如果您能帮我解决这个问题或提供任何有用的建议,我将不胜感激。

【问题讨论】:

    标签: c++ opencv tensorflow2.0 object-detection-api resnet


    【解决方案1】:

    可以使用带有对象检测 API 和 Opencv 的 Tensorflow 2 模型,如专用 wiki 中所述:https://github.com/opencv/opencv/wiki/TensorFlow-Object-Detection-API

    到目前为止,它们与 Tensorflow 1 兼容的模型更多,但对于 SSD 来说应该没问题。 要冻结您的图表,您必须这样做:

    import tensorflow as tf
    
    from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2
    
    loaded = tf.saved_model.load('my_model')
    infer = loaded.signatures['serving_default']
    
    f = tf.function(infer).get_concrete_function(input_1=tf.TensorSpec(shape=[None, 224, 224, 3], dtype=tf.float32))
    f2 = convert_variables_to_constants_v2(f)
    graph_def = f2.graph.as_graph_def()
    
    # Export frozen graph
    with tf.io.gfile.GFile('frozen_graph.pb', 'wb') as f:
       f.write(graph_def.SerializeToString())
    

    正如 OpenCV Github 问题中的评论所述:https://github.com/opencv/opencv/issues/16582#issuecomment-603819498

    然后您可能需要使用 OpenCV wiki 中提供的 tf_text_graph_ssd.py 来生成冻结模型的文本图形表示,就是这样!

    【讨论】:

    • 我用过这段代码,但它对我不起作用。我收到错误ValueError: Input 1 of node StatefulPartitionedCall was passed float from 53831:0 incompatible with expected resource. 你知道怎么解决吗?同样正如我在问题中提到的,我想使用 OpenCV C++,而不是 Python。
    • c++ 应该不会造成任何问题。至于引发的错误,我不知道抱歉。您可以尝试启动脚本以使用 Tensorflow 1.15 或更低版本冻结模型。
    【解决方案2】:

    Tensorflow 2 不再支持会话,因此您无法轻松地将模型导出为冻结图。我找到了this,它解决了我在使用 Opencv 的 Tensorflow 对象检测模型时遇到的问题。希望这会有所帮助。

    【讨论】:

    • 感谢您的回复,我会阅读这篇文章。您能告诉我您使用哪个版本的 Tensorflow 进行培训吗?
    • 在 colab 版本:1.15.2 上训练
    猜你喜欢
    • 2021-02-01
    • 2023-03-23
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多