|
- # Copyright 2021 The KubeEdge Authors.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
-
- import os
- import logging
-
- import cv2
- import numpy as np
- import tensorflow as tf
-
- LOG = logging.getLogger(__name__)
- os.environ['BACKEND_TYPE'] = 'TENSORFLOW'
- flags = tf.flags.FLAGS
-
-
- def create_input_feed(sess, new_image, img_data):
- """Create input feed for edge model inference"""
- input_feed = {}
-
- input_img_data = sess.graph.get_tensor_by_name('images:0')
- input_feed[input_img_data] = new_image
-
- input_img_shape = sess.graph.get_tensor_by_name('shapes:0')
- input_feed[input_img_shape] = [img_data.shape[0], img_data.shape[1]]
-
- return input_feed
-
-
- def create_output_fetch(sess):
- """Create output fetch for edge model inference"""
- output_classes = sess.graph.get_tensor_by_name('concat_19:0')
- output_scores = sess.graph.get_tensor_by_name('concat_18:0')
- output_boxes = sess.graph.get_tensor_by_name('concat_17:0')
-
- output_fetch = [output_classes, output_scores, output_boxes]
- return output_fetch
-
-
- class Estimator:
-
- def __init__(self, **kwargs):
- """
- initialize logging configuration
- """
- graph = tf.Graph()
- config = tf.ConfigProto(allow_soft_placement=True)
- config.gpu_options.allow_growth = True
- config.gpu_options.per_process_gpu_memory_fraction = 0.1
- self.session = tf.Session(graph=graph, config=config)
- self.input_shape = [416, 736]
- self.create_input_feed = create_input_feed
- self.create_output_fetch = create_output_fetch
-
- def load(self, model_url=""):
- with self.session.as_default():
- with self.session.graph.as_default():
- with tf.gfile.FastGFile(model_url, 'rb') as handle:
- LOG.info(f"Load model {model_url}, "
- f"ParseFromString start .......")
- graph_def = tf.GraphDef()
- graph_def.ParseFromString(handle.read())
- LOG.info("ParseFromString end .......")
-
- tf.import_graph_def(graph_def, name='')
- LOG.info("Import_graph_def end .......")
-
- LOG.info("Import model from pb end .......")
-
- @staticmethod
- def preprocess(image, input_shape):
- """Preprocess functions in edge model inference"""
-
- # resize image with unchanged aspect ratio using padding by opencv
-
- h, w, _ = image.shape
-
- input_h, input_w = input_shape
- scale = min(float(input_w) / float(w), float(input_h) / float(h))
- nw = int(w * scale)
- nh = int(h * scale)
-
- image = cv2.resize(image.astype(np.float32), (nw, nh))
-
- new_image = np.zeros((input_h, input_w, 3), np.float32)
- new_image.fill(128)
- bh, bw, _ = new_image.shape
- new_image[int((bh - nh) / 2):(nh + int((bh - nh) / 2)),
- int((bw - nw) / 2):(nw + int((bw - nw) / 2)), :] = image
-
- new_image /= 255.
- new_image = np.expand_dims(new_image, 0) # Add batch dimension.
- return new_image
-
- @staticmethod
- def postprocess(model_output):
- all_classes, all_scores, all_bboxes = model_output
- bboxes = []
- for c, s, bbox in zip(all_classes, all_scores, all_bboxes):
- bbox[0], bbox[1], bbox[2], bbox[3] = bbox[1].tolist(
- ), bbox[0].tolist(), bbox[3].tolist(), bbox[2].tolist()
- bboxes.append(bbox.tolist() + [s.tolist(), c.tolist()])
-
- return bboxes
-
- def predict(self, data, **kwargs):
- img_data_np = np.array(data)
- with self.session.as_default():
- new_image = self.preprocess(img_data_np, self.input_shape)
- input_feed = self.create_input_feed(
- self.session, new_image, img_data_np)
- output_fetch = self.create_output_fetch(self.session)
- output = self.session.run(output_fetch, input_feed)
- return self.postprocess(output)
|