无法将tensorflow冻结图转换为pbtxt文件

时间:2019-07-12 13:11:41

标签: python opencv tensorflow deep-learning computer-vision

鉴于张量流冻结推理图的输入,我想提取pbtxt文件。为此,我使用以下脚本:

import tensorflow as tf

#from google.protobuf import text_format
from tensorflow.python.platform import gfile

def converter(filename): 
  with gfile.FastGFile(filename,'rb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())
    tf.import_graph_def(graph_def, name='')
    tf.train.write_graph(graph_def, 'pbtxt/', 'protobuf.pbtxt', as_text=True)
    print(graph_def)
  return


#converter('ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb')  # here you can write the name of the file to be converted
# and then a new file will be made in pbtxt directory.

converter('ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb')

作为示例,我正在使用ssd mobilenet体系结构。使用上面的代码,我得到的输出为pbtxt,但是我不能使用它。供参考,请参见下图

enter image description here

  

右:移动网络体系结构的原始pbtxt文件的图像

     

左:使用上述脚本获得的pbtxt文件的图像。

当我使用右边的官方pbtxt时,我会得到正确的结果。但是,当我使用上面的脚本生成的LEFT pbtxt时,我没有得到任何预测

我在开放式Cv DNN模块上使用这些预测

tensorflowNet = cv2.dnn.readNetFromTensorflow('ssd_mobilenet_v1_coco_2017_11_17/frozen_inference_graph.pb', 'pbtxt/protobuf.pbtxt')

如何将mobilenet冻结的推理图转换为正确的pbtxt格式,以便进行推理?

参考: https://gist.github.com/Arafatk/c063bddb9b8d17a037695d748db4f592

4 个答案:

答案 0 :(得分:0)

请遵循以下指南:https://github.com/opencv/opencv/wiki/TensorFlow-Object-Detection-API。如果不修改.pbtxt,就没有意义。指南中的脚本会创建一个额外的文本图,该文本图可用于导入到OpenCV。

答案 1 :(得分:0)

这对我有用

  • git clone https://github.com/opencv/opencv.git
  • 导航到opencv / samples / dnn /
  • 复制Frozen_inference_graph.pb和与您的pb文件相对应的* .config文件
  • 将复制的文件粘贴到opencv / samples / dnn目录中
  • 在den目录中新建一个文件夹,并将其命名为“ exported_pbtxt”

并运行以下脚本:

python3 tf_text_graph_ssd.py --input frozen_inference_graph.pb --output exported_pbtxt/output.pbtxt --config pipeline.config

enter image description here

这就是您所需要的,现在复制冻结的推理图和新生成的pbtxt文件。并且,使用以下脚本通过OpenCV运行模型:

import cv2

# Load a model imported from Tensorflow
tensorflowNet = cv2.dnn.readNetFromTensorflow('card_graph/frozen_inference_graph.pb', 'exported_pbtxt/output.pbtxt')

# Input image
img = cv2.imread('image.jpg')
rows, cols, channels = img.shape

# Use the given image as input, which needs to be blob(s).
tensorflowNet.setInput(cv2.dnn.blobFromImage(img, size=(300, 300), swapRB=True, crop=False))

# Runs a forward pass to compute the net output
networkOutput = tensorflowNet.forward()

# Loop on the outputs
for detection in networkOutput[0,0]:

    score = float(detection[2])
    if score > 0.9:

        left = detection[3] * cols
        top = detection[4] * rows
        right = detection[5] * cols
        bottom = detection[6] * rows

        #draw a red rectangle around detected objects
        cv2.rectangle(img, (int(left), int(top)), (int(right), int(bottom)), (0, 0, 255), thickness=2)

# Show the image with a rectagle surrounding the detected objects 
cv2.imshow('Image', img)
cv2.waitKey()
cv2.destroyAllWindows()

答案 2 :(得分:0)

可能会帮助某人。从master提取的OpenCV 4.3.0的mars-small128.pb遇到了相同的问题

import argparse
import tensorflow as tf
from tensorflow.python.saved_model import signature_constants

def save(graph_pb, export_dir):
builder = tf.saved_model.builder.SavedModelBuilder(export_dir)

with tf.gfile.GFile(graph_pb, "rb") as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())

sigs = {}

with tf.Session(graph=tf.Graph()) as sess:
    # INFO: name="" is important to ensure we don't get spurious prefixing
    tf.import_graph_def(graph_def, name='')
    g = tf.get_default_graph()

    # INFO: if name is added the input/output should be prefixed like:
    #       name=net => net/images:0 & net/features:0
    inp = tf.get_default_graph().get_tensor_by_name("images:0")
    out = tf.get_default_graph().get_tensor_by_name("features:0")

    sigs[signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY] = \
        tf.saved_model.signature_def_utils.predict_signature_def(
            {"in": inp}, {"out": out})

    builder.add_meta_graph_and_variables(sess,
                                         [tag_constants.SERVING],
                                         signature_def_map=sigs)

builder.save(as_text=True)


if __name__ == '__main__':
    # export_dir = './saved'
    # graph_pb = '../models/deep_sort/mars-small128.pb'

    parser = argparse.ArgumentParser()
    parser.add_argument('--input', help="path to frozen pb file")
    parser.add_argument('--output', help="Folder to save")
    args = parser.parse_args()
    if args.input is not None and args.output:
        save(args.input, args.output)
    else:
        print(f"Usage adapt_opencv.py.py --input 'path_to_bp' --output './saved'")

答案 3 :(得分:0)

将 pb 转换为 TF 2.xxx 的 pbtxt:

import tensorflow as tf
from google.protobuf import text_format
from tensorflow.python.platform import gfile

def graphdef_to_pbtxt(filename): 
    with open(filename,'rb') as f:
        graph_def = tf.compat.v1.GraphDef()
        graph_def.ParseFromString(f.read())
    with open('protobuf.txt', 'w') as fp:
        fp.write(str(graph_def))
    
graphdef_to_pbtxt('saved_model.pb')