From 253a4286741d3382c84d9161bc678b54baf4c4b0 Mon Sep 17 00:00:00 2001 From: LiZeB <963899158@qq.com> Date: Mon, 13 May 2019 15:59:20 +0800 Subject: [PATCH 1/3] fix the bug which can't use in python3.; Increase the compatibility between python2. and python3. --- .idea/MultiNet.iml | 11 ++++++ .idea/inspectionProfiles/Project_Default.xml | 14 ++++++++ .idea/misc.xml | 7 ++++ .idea/modules.xml | 8 +++++ .idea/vcs.xml | 37 ++++++++++++++++++++ 5 files changed, 77 insertions(+) create mode 100644 .idea/MultiNet.iml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/MultiNet.iml b/.idea/MultiNet.iml new file mode 100644 index 0000000..5c88ce7 --- /dev/null +++ b/.idea/MultiNet.iml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..7972536 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..3446b3f --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..b9e755e --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..cf41716 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 81f6b7a63242fa9a3fd1a9a2a6a106a86ea4f69c Mon Sep 17 00:00:00 2001 From: LiZeB <963899158@qq.com> Date: Fri, 17 May 2019 10:41:38 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E8=87=AA?= =?UTF-8?q?=E5=B7=B1=E7=9A=84=E6=B5=8B=E8=AF=95=E6=96=87=E4=BB=B6demo2.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo2.py | 288 +++++++++++++++++++++++++++++++++++++++++++++++ subhypes_test.py | 0 2 files changed, 288 insertions(+) create mode 100644 demo2.py create mode 100644 subhypes_test.py diff --git a/demo2.py b/demo2.py new file mode 100644 index 0000000..6ad87ac --- /dev/null +++ b/demo2.py @@ -0,0 +1,288 @@ +import os +import sys +import cv2 +import logging +import numpy as np +from PIL import Image, ImageDraw, ImageFont +import tensorflow as tf +sys.path.insert(1, 'incl') +try: + import tensorvision.utils as tv_utils + import tensorvision.core as core +except ImportError: + logging.error("Could not import the submodules.") + logging.error("Please execute:""'git submodule update --init --recursive'") + exit(1) +sys.path.append("submodules/KittiBox/submodules/") +try: + import utils.train_utils as dec_utils +except ImportError: + logging.error("Could not import submodules/KittiBox/submodules/utils") + exit(-1) + +flags = tf.app.flags +FLAGS = flags.FLAGS +flags.DEFINE_string('logdir', None, 'Path to logdir.') +flags.DEFINE_string('input', "data/demo/um_000014.png", 'Image to apply KittiSeg.') +flags.DEFINE_string('output', None, 'Image to apply KittiSeg.') +logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO, stream=sys.stdout) + +def road_draw(image, highway): + im = Image.fromarray(image.astype('uint8')) + draw = ImageDraw.Draw(im) + fnt = ImageFont.truetype('FreeMono/FreeMonoBold.ttf', 40) + shape = image.shape + + if highway: + draw.text((65, 10), "Highway", + font=fnt, fill=(255, 255, 0, 255)) + draw.ellipse([10, 10, 55, 55], fill=(255, 255, 0, 255), + outline=(255, 255, 0, 255)) + else: + draw.text((65, 10), "minor road", + font=fnt, fill=(255, 0, 0, 255)) + draw.ellipse([10, 10, 55, 55], fill=(255, 0, 0, 255), + outline=(255, 0, 0, 255)) + + return np.array(im).astype('float32') + +def load_united_model(logdir): + subhypes = {} + submodules = {} + + # 加载参数文件,meta_hypes是总的参数文件 + ### 这一个函数的作用就是从hypes.json这个超参数文件中加载超参数; + ### 因为hypes.json中的路径参数是绝对路径,所以要跨平台使用时必须用代码进行修改; + ### hypes.json中的参数分为:1.文件路径参数dirs;2.训练时的显示参数logging; + ### 3.损失函数的参数:loss_build; 4.模型列表model_list; 5.模型描述文件(三个模型都是用.json文件描述)models; + ### 6.优化方法参数solver + meta_hypes = tv_utils.load_hypes_from_logdir(logdir, subdir="", base_path='hypes') + ###: {'dirs': {'base_path': '/home/lizebin/tensorflow/Detection/MultiNet/hypes', + # 'data_dir': 'DATA', 'image_dir': '/home/lizebin/tensorflow/Detection/MultiNet/RUNS/MultiNet_ICCV/images', + # 'output_dir': '/home/lizebin/tensorflow/Detection/MultiNet/RUNS/MultiNet_ICCV'}, + # 'logging': {'display_iter': 50, 'eval_iter': 1000, 'image_iter': 600000, 'save_iter': 5000, 'write_iter': 1000}, + # 'loss_build': {'recombine': True, 'weighted': False, 'weights': [0.7, 2, 0.7]}, + # 'model_list': ['segmentation', 'detection', 'road'], + # 'models': {'detection': '../submodules/KittiBox/hypes/kittiBox.json', + # 'road': '../submodules/KittiClass/hypes/KittiClass_VGG.json', + # 'segmentation': '../submodules/KittiSeg/hypes/KittiVGG.json'}, + # 'path': ['../incl', '../submodules/KittiSeg/incl', '../submodules/KittiBox/incl/', '../submodules/KittiClass/incl/'], + # 'selection': {'random': False, 'use_weights': True, 'weights': [1, 0, 0]}, + # 'solver': {'batch_size': 1, 'max_steps': 100000}} + + #加载模型的各个模块,hypes代表模型的参数文件,modules和submodules[modules]代表模型的组成模块 + for model in meta_hypes['models']: + subhypes[model] = tv_utils.load_hypes_from_logdir(logdir, subdir=model) + hypes = subhypes[model] + # : {'arch': {'deep_feat': 'pool5'}, + # 'augment_level': 1, 'batch_size': 5, 'biggest_box_px': 10000, 'clip_norm': 1.0, + # 'data': {'eval_cmd': '../submodules/KittiObjective2/./evaluate_object2', + # 'label_dir': 'KittiBox/training/label_2', 'train_file': 'KittiBox/train.txt', + # 'truncate_data': False, 'val_file': 'KittiBox/val.txt'}, 'detect_truck': False, + # 'dirs': {'base_path': '/home/mifs/mttt2/github/MultiNet/submodules/KittiBox/hypes', + # 'data_dir': 'DATA', 'image_dir': '/home/lizebin/tensorflow/Detection/MultiNet/RUNS/MultiNet_ICCV/images', + # 'output_dir': '/home/lizebin/tensorflow/Detection/MultiNet/RUNS/MultiNet_ICCV'}, + # 'early_feat_channels': 256, 'focus_size': 1.8, 'grid_height': 12, 'grid_width': 39, + # 'image_height': 384, 'image_width': 1248, + # 'logging': {'display_iter': 200, 'eval_iter': 2000, 'image_iter': 10000, 'save_iter': 2000, + # 'write_iter': 800}, 'model': {'architecture_file': '../encoder/vgg.py', + # 'evaluator_file': '../evals/kitti_eval.py', 'input_file': '../inputs/kitti_input.py', + # 'objective_file': '../decoder/fastBox.py', 'optimizer_file': '../optimizer/generic_optimizer.py'}, + # 'num_classes': 2, 'num_inner_channel': 500, 'path': ['../incl'], 'region_size': 32, + # 'rezoom_change_loss': 'center', 'rezoom_h_coords': [-0.25, 0, 0.25], + # 'rezoom_w_coords': [-0.25, 0, 0.25], 'scale_down': 0.1, + # 'solver': {'batch_size': 1, 'epsilon': 1e-05, 'head_weights': [1.0, 0.1], + # 'hungarian_iou': 0.35, 'learning_rate': 1e-05, 'learning_rate_step': None, + # 'max_steps': 140000, 'opt': 'Adam', 'rnd_seed': 1, 'use_jitter': True, 'weights': ''}, + # 'tau': 0.35, 'use_mask': True, 'use_rezoom': True, 'wd': 0.0005} + hypes['dirs']['output_dir'] = meta_hypes['dirs']['output_dir'] + hypes['dirs']['image_dir'] = meta_hypes['dirs']['image_dir'] + submodules[model] = tv_utils.load_modules_from_logdir(logdir, dirname=model, postfix=model) + + ### dict_keys(['input', 'arch', 'objective', 'solver', 'eval'])加载了这5个模块代表一个模型 + ### submodules[module]代表一个模型的5个模块 + modules = submodules[model] + + return meta_hypes, subhypes, submodules + +def eval_model(logdir, meta_hypes, subhypes, submodules): + first_iter = True + + image_pl = tf.placeholder(tf.float32) + image = tf.expand_dims(image_pl, 0) + image.set_shape([1, 384, 1248, 3]) + + decoded_logits = {} + for model in meta_hypes['models']: + hypes = subhypes[model] ### subhypes[modle]是各个模型的参数文件 + modules = submodules[model] ### submodules[model]是模型的各个组件 + optimizer = modules['solver'] + + with tf.name_scope('Validation_%s' % model): + reuse = {True: False, False: True}[first_iter] + + scope = tf.get_variable_scope() + + with tf.variable_scope(scope, reuse=reuse): + ### inference()函数的输出结果是vgg_dict = {'deep_feat': deep_feat,'early_feat': vgg_fcn.conv4_3} + ### 这里输出的是一个用来计算交叉熵的tensorflow:softmax_linear: Output tensor with the computed logits. + logits = modules['arch'].inference(hypes, image, train=False) + + # """Apply decoder to the logits. + # + # Computation which decode CNN boxes. + # The output can be interpreted as bounding Boxes. + # Args: + # logits: Logits tensor, output von encoder + # + # Return: + # decoded_logits: values which can be interpreted as bounding boxes + # """ + # decoded_logits[model]是一个字典,是对bounding box的预测。dict_keys(['pred_confs_deltas', + # 'pred_boxes_deltas', 'pred_boxes_new', 'pred_boxes', 'pred_logits', 'pred_confidences']) + decoded_logits[model] = modules['objective'].decoder(hypes, logits, train=False) + + first_iter = False + sess = tf.Session() + saver = tf.train.Saver() + + # """ + # Load the weights of a model stored in saver. + # + # Parameters + # ---------- + # checkpoint_dir : str + # The directory of checkpoints. + # sess : tf.Session + # A Session to use to restore the parameters. + # saver : tf.train.Saver + # + # Returns + # ----------- + # int + # training step of checkpoint + # """ + cur_step = core.load_weights(logdir, sess, saver) + + return meta_hypes, subhypes, submodules, decoded_logits, sess, image_pl + +def main(): + logdir = os.path.join("RUNS", "MultiNet_ICCV") + meta_hypes, subhypes, submodules = load_united_model(logdir) ### 从RUN/MultiNet_ICCV下加载模型 + load_out = eval_model(logdir, meta_hypes, subhypes, submodules) + + # Create list of relevant tensors to evaluate + ### meata_hypes是总的参数文件hypes.json; + ### subhypes是各个模型的参数文件; + ### submoudles是各个模型的组成模块; + ### decoded_logits在detection时是bounding box的预测; + ### sesss是会话管理环境; + ### image_pl是图片输入tensor + meta_hypes, subhypes, submodules, decoded_logits, sess, image_pl = load_out + + seg_softmax = decoded_logits['segmentation']['softmax'] + pred_boxes_new = decoded_logits['detection']['pred_boxes_new'] + pred_confidences = decoded_logits['detection']['pred_confidences'] + if len(meta_hypes['model_list']) == 3: + road_softmax = decoded_logits['road']['softmax'][0] + else: + road_softmax = None + + eval_list = [seg_softmax, pred_boxes_new, pred_confidences, road_softmax] + + hypes_road = subhypes['road'] + image = cv2.imread(FLAGS.input) + shape = image.shape + image_height = hypes_road['jitter']['image_height'] + image_width = hypes_road['jitter']['image_width'] + assert (image_height >= shape[0]) + assert (image_width >= shape[1]) + image = cv2.resize(image, (image_height, image_width), interpolation=cv2.INTER_CUBIC) + + ### Run KittiSeg model on image + ### eval_list = [seg_softmax, pred_boxes_new, pred_confidences, road_softmax] + feed_dict = {image_pl: image} + output = sess.run(eval_list, feed_dict=feed_dict) + seg_softmax, pred_boxes_new, pred_confidences, road_softmax = output + + # Create Segmentation Overlay + # """ + # Overlay input_image with a hard segmentation result for two classes. + # Store the result with the same name as segmentation_image, but with + # `-overlay`. + # + # Parameters + # ---------- + # input_image : numpy.array + # An image of shape [width, height, 3]. + # segmentation : numpy.array + # Segmentation of shape [width, height]. + # color: color for forground class + # + # Returns + # ------- + # numpy.array + # The image overlayed with the segmenation + # """ + shape = image.shape + seg_softmax = seg_softmax[:, 1].reshape(shape[0], shape[1]) + hard = seg_softmax > 0.5 + overlay_image = tv_utils.fast_overlay(image, hard) + + # Draw Detection Boxes + new_img, rects = dec_utils.add_rectangles( + subhypes['detection'], [overlay_image], pred_confidences, + pred_boxes_new, show_removed=False, + use_stitching=True, rnn_len=subhypes['detection']['rnn_len'], + min_conf=0.50, tau=subhypes['detection']['tau']) + + # Draw road classification + highway = (np.argmax(road_softmax) == 1) + new_img = road_draw(new_img, highway) + + ### 在终端上打印出预测的结果:检测到的车辆数; + ### Printing some more output information + ### removing predictions <= threshold + ### Printing coordinates of predicted rects. + logging.info("") + threshold = 0.5 + accepted_predictions = [] + for rect in rects: + if rect.score >= threshold: + accepted_predictions.append(rect) + print('') + logging.info("{} Cars detected".format(len(accepted_predictions))) + for i, rect in enumerate(accepted_predictions): + logging.info("") + logging.info("Coordinates of Box {}".format(i)) + logging.info(" x1: {}".format(rect.x1)) + logging.info(" x2: {}".format(rect.x2)) + logging.info(" y1: {}".format(rect.y1)) + logging.info(" y2: {}".format(rect.y2)) + logging.info(" Confidence: {}".format(rect.score)) + if len(meta_hypes['model_list']) == 3: + logging.info("Raw Classification Softmax outputs are: {}" + .format(output[0][0])) + + # Save output image file + if FLAGS.output is None: + output_base_name = FLAGS.input + out_image_name = output_base_name.split('.')[0] + '_out.png' + else: + out_image_name = FLAGS.output + cv2.imwrite(out_image_name, new_img) + + logging.info("") + logging.info("Output image has been saved to: {}".format(os.path.realpath(out_image_name))) + logging.info("") + logging.warning("Do NOT use this Code to evaluate multiple images.") + logging.warning("Demo.py is **very slow** and designed " + "to be a tutorial to show how the MultiNet works.") + logging.warning("") + logging.warning("Please see this comment, if you like to apply demo.py to multiple images see:") + logging.warning("https://github.com/MarvinTeichmann/KittiBox/issues/15#issuecomment-301800058") + + exit(0) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/subhypes_test.py b/subhypes_test.py new file mode 100644 index 0000000..e69de29 From ae4c444bbde350b1ebd4e430272fa1b6270f5b2f Mon Sep 17 00:00:00 2001 From: LiZeB <963899158@qq.com> Date: Fri, 17 May 2019 15:34:49 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86demo.py,?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BA=86=E4=B8=80=E4=BA=9B=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E7=9A=84=E4=BB=A3=E7=A0=81=E3=80=82=E6=8E=A5=E4=B8=8B=E6=9D=A5?= =?UTF-8?q?=E8=A6=81=E5=AF=B9demo.py=E7=BB=A7=E7=BB=AD=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=8C=E7=BC=A9=E7=9F=AD=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- demo.py | 187 +++++------------------------------- demo2.py | 288 ------------------------------------------------------- 2 files changed, 25 insertions(+), 450 deletions(-) delete mode 100644 demo2.py diff --git a/demo.py b/demo.py index eca0244..144e640 100644 --- a/demo.py +++ b/demo.py @@ -1,12 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# -# Author: Marvin Teichmann - - -""" +''' Detects Cars in an image using KittiSeg. - Input: Image Output: Image (with Cars plotted in Green) @@ -16,62 +11,36 @@ Usage: python demo.py --input data/demo.png [--output_image output_image] [--logdir /path/to/weights] [--gpus 0] - - -""" -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function +''' import json import logging import os import sys - import collections - -# configure logging - -logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', - level=logging.INFO, - stream=sys.stdout) - -# https://github.com/tensorflow/tensorflow/issues/2034#issuecomment-220820070 import numpy as np import scipy as scp import scipy.misc import tensorflow as tf - import time - +import argparse from PIL import Image, ImageDraw, ImageFont - -flags = tf.app.flags -FLAGS = flags.FLAGS - +logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO, stream=sys.stdout) sys.path.insert(1, 'incl') - try: - # Check whether setup was done correctly - import tensorvision.utils as tv_utils import tensorvision.core as core except ImportError: - # You forgot to initialize submodules logging.error("Could not import the submodules.") - logging.error("Please execute:" - "'git submodule update --init --recursive'") + logging.error("Please execute:'git submodule update --init --recursive'") exit(1) - -flags.DEFINE_string('logdir', None, - 'Path to logdir.') -flags.DEFINE_string('input', None, - 'Image to apply KittiSeg.') -flags.DEFINE_string('output', None, - 'Image to apply KittiSeg.') - +parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS) +parser.add_argument('--logdir', type=str, default='None', help= "Path to logdir") +parser.add_argument('--input', type=str, default='data/demo/um_000014.png', help= "Image to apply KittiSeg.") +parser.add_argument('--output', type=str, default='None', help= "Image to apply KittiSeg.") +FLAGS = parser.parse_args() default_run = 'MultiNet_ICCV' weights_url = ("ftp://mi.eng.cam.ac.uk/" @@ -98,61 +67,6 @@ def maybe_download_and_extract(runs_dir): return - -def resize_label_image(image, gt_image, image_height, image_width): - image = scp.misc.imresize(image, size=(image_height, image_width), - interp='cubic') - shape = gt_image.shape - gt_image = scp.misc.imresize(gt_image, size=(image_height, image_width), - interp='nearest') - - return image, gt_image - - -def _output_generator(sess, tensor_list, image_pl, data_file, - process_image=lambda x: x): - image_dir = os.path.dirname(data_file) - with open(data_file) as file: - for datum in file: - datum = datum.rstrip() - image_file = datum.split(" ")[0] - image_file = os.path.join(image_dir, image_file) - - image = scp.misc.imread(image_file) - - image = process_image(image) - - feed_dict = {image_pl: image} - start_time = time.time() - output = sess.run(tensor_list, feed_dict=feed_dict) - yield image_file, output - - -def eval_runtime(sess, subhypes, image_pl, eval_list, data_file): - logging.info(' ') - logging.info('Evaluation complete. Measuring runtime.') - image_dir = os.path.dirname(data_file) - with open(data_file) as file: - for datum in file: - datum = datum.rstrip() - image_file = datum.split(" ")[0] - image_file = os.path.join(image_dir, image_file) - image = scp.misc.imread(image_file) - image = process_image(subhypes, image) - feed = {image_pl: image} - for i in xrange(100): - _ = sess.run(eval_list, feed_dict=feed) - start_time = time.time() - for i in xrange(100): - _ = sess.run(eval_list, feed_dict=feed) - dt = (time.time() - start_time)/100 - logging.info('Joined inference can be conducted at the following rates on' - ' your machine:') - logging.info('Speed (msec): %f ', 1000*dt) - logging.info('Speed (fps): %f ', 1/dt) - return dt - - def test_constant_input(subhypes): road_input_conf = subhypes['road']['jitter'] seg_input_conf = subhypes['segmentation']['jitter'] @@ -219,40 +133,17 @@ def road_draw(image, highway): return np.array(im).astype('float32') - -def process_image(subhypes, image): - hypes = subhypes['road'] - shape = image.shape - image_height = hypes['jitter']['image_height'] - image_width = hypes['jitter']['image_width'] - assert(image_height >= shape[0]) - assert(image_width >= shape[1]) - - image = scp.misc.imresize(image, (image_height, - image_width, 3), - interp='cubic') - return image - - def load_united_model(logdir): subhypes = {} - subgraph = {} submodules = {} - subqueues = {} - first_iter = True - - meta_hypes = tv_utils.load_hypes_from_logdir(logdir, subdir="", - base_path='hypes') + meta_hypes = tv_utils.load_hypes_from_logdir(logdir, subdir="", base_path='hypes') for model in meta_hypes['models']: subhypes[model] = tv_utils.load_hypes_from_logdir(logdir, subdir=model) hypes = subhypes[model] hypes['dirs']['output_dir'] = meta_hypes['dirs']['output_dir'] hypes['dirs']['image_dir'] = meta_hypes['dirs']['image_dir'] - submodules[model] = tv_utils.load_modules_from_logdir(logdir, - dirname=model, - postfix=model) - + submodules[model] = tv_utils.load_modules_from_logdir(logdir, dirname=model, postfix=model) modules = submodules[model] image_pl = tf.placeholder(tf.float32) @@ -266,14 +157,10 @@ def load_united_model(logdir): with tf.name_scope('Validation_%s' % model): reuse = {True: False, False: True}[first_iter] - scope = tf.get_variable_scope() - with tf.variable_scope(scope, reuse=reuse): logits = modules['arch'].inference(hypes, image, train=False) - - decoded_logits[model] = modules['objective'].decoder(hypes, logits, - train=False) + decoded_logits[model] = modules['objective'].decoder(hypes, logits, train=False) first_iter = False sess = tf.Session() @@ -283,10 +170,10 @@ def load_united_model(logdir): return meta_hypes, subhypes, submodules, decoded_logits, sess, image_pl -def main(_): +def main(): tv_utils.set_gpus_to_use() - if FLAGS.input is None: + if FLAGS.input == 'None': logging.error("No input was given.") logging.info( "Usage: python demo.py --input data/test.png " @@ -294,13 +181,8 @@ def main(_): "[--gpus GPUs_to_use] ") exit(1) - if FLAGS.logdir is None: - # Download and use weights from the MultiNet Paper - if 'TV_DIR_RUNS' in os.environ: - runs_dir = os.path.join(os.environ['TV_DIR_RUNS'], - 'MultiNet') - else: - runs_dir = 'RUNS' + if FLAGS.logdir == 'None': + runs_dir = 'RUNS' maybe_download_and_extract(runs_dir) logdir = os.path.join(runs_dir, default_run) else: @@ -330,6 +212,7 @@ def main(_): test_segmentation_input(subhypes) # Load and reseize Image + image_file = FLAGS.input image = scp.misc.imread(image_file) @@ -339,17 +222,12 @@ def main(_): image_width = hypes_road['jitter']['image_width'] assert(image_height >= shape[0]) assert(image_width >= shape[1]) - - image = scp.misc.imresize(image, (image_height, - image_width, 3), - interp='cubic') - - import utils.train_utils as dec_utils + image = scp.misc.imresize(image, (image_height, image_width, 3), interp='cubic') # Run KittiSeg model on image feed_dict = {image_pl: image} output = sess.run(eval_list, feed_dict=feed_dict) - + sess.close() seg_softmax, pred_boxes_new, pred_confidences, road_softmax = output # Create Segmentation Overlay @@ -359,6 +237,7 @@ def main(_): overlay_image = tv_utils.fast_overlay(image, hard) # Draw Detection Boxes + import utils.train_utils as dec_utils new_img, rects = dec_utils.add_rectangles( subhypes['detection'], [overlay_image], pred_confidences, pred_boxes_new, show_removed=False, @@ -370,7 +249,6 @@ def main(_): new_img = road_draw(new_img, highway) logging.info("") - # Printing some more output information threshold = 0.5 accepted_predictions = [] @@ -393,34 +271,19 @@ def main(_): logging.info(" Confidence: {}".format(rect.score)) if len(meta_hypes['model_list']) == 3: - logging.info("Raw Classification Softmax outputs are: {}" - .format(output[0][0])) + logging.info("Raw Classification Softmax outputs are: {}".format(output[0][0])) # Save output image file - if FLAGS.output is None: + if FLAGS.output == 'None': output_base_name = FLAGS.input out_image_name = output_base_name.split('.')[0] + '_out.png' else: out_image_name = FLAGS.output - scp.misc.imsave(out_image_name, new_img) logging.info("") - logging.info("Output image has been saved to: {}".format( - os.path.realpath(out_image_name))) - - logging.info("") - logging.warning("Do NOT use this Code to evaluate multiple images.") - - logging.warning("Demo.py is **very slow** and designed " - "to be a tutorial to show how the MultiNet works.") - logging.warning("") - logging.warning("Please see this comment, if you like to apply demo.py to" - " multiple images see:") - logging.warning("https://github.com/MarvinTeichmann/KittiBox/" - "issues/15#issuecomment-301800058") - + logging.info("Output image has been saved to: {}".format(os.path.realpath(out_image_name))) exit(0) if __name__ == '__main__': - tf.app.run() + main() diff --git a/demo2.py b/demo2.py deleted file mode 100644 index 6ad87ac..0000000 --- a/demo2.py +++ /dev/null @@ -1,288 +0,0 @@ -import os -import sys -import cv2 -import logging -import numpy as np -from PIL import Image, ImageDraw, ImageFont -import tensorflow as tf -sys.path.insert(1, 'incl') -try: - import tensorvision.utils as tv_utils - import tensorvision.core as core -except ImportError: - logging.error("Could not import the submodules.") - logging.error("Please execute:""'git submodule update --init --recursive'") - exit(1) -sys.path.append("submodules/KittiBox/submodules/") -try: - import utils.train_utils as dec_utils -except ImportError: - logging.error("Could not import submodules/KittiBox/submodules/utils") - exit(-1) - -flags = tf.app.flags -FLAGS = flags.FLAGS -flags.DEFINE_string('logdir', None, 'Path to logdir.') -flags.DEFINE_string('input', "data/demo/um_000014.png", 'Image to apply KittiSeg.') -flags.DEFINE_string('output', None, 'Image to apply KittiSeg.') -logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO, stream=sys.stdout) - -def road_draw(image, highway): - im = Image.fromarray(image.astype('uint8')) - draw = ImageDraw.Draw(im) - fnt = ImageFont.truetype('FreeMono/FreeMonoBold.ttf', 40) - shape = image.shape - - if highway: - draw.text((65, 10), "Highway", - font=fnt, fill=(255, 255, 0, 255)) - draw.ellipse([10, 10, 55, 55], fill=(255, 255, 0, 255), - outline=(255, 255, 0, 255)) - else: - draw.text((65, 10), "minor road", - font=fnt, fill=(255, 0, 0, 255)) - draw.ellipse([10, 10, 55, 55], fill=(255, 0, 0, 255), - outline=(255, 0, 0, 255)) - - return np.array(im).astype('float32') - -def load_united_model(logdir): - subhypes = {} - submodules = {} - - # 加载参数文件,meta_hypes是总的参数文件 - ### 这一个函数的作用就是从hypes.json这个超参数文件中加载超参数; - ### 因为hypes.json中的路径参数是绝对路径,所以要跨平台使用时必须用代码进行修改; - ### hypes.json中的参数分为:1.文件路径参数dirs;2.训练时的显示参数logging; - ### 3.损失函数的参数:loss_build; 4.模型列表model_list; 5.模型描述文件(三个模型都是用.json文件描述)models; - ### 6.优化方法参数solver - meta_hypes = tv_utils.load_hypes_from_logdir(logdir, subdir="", base_path='hypes') - ###: {'dirs': {'base_path': '/home/lizebin/tensorflow/Detection/MultiNet/hypes', - # 'data_dir': 'DATA', 'image_dir': '/home/lizebin/tensorflow/Detection/MultiNet/RUNS/MultiNet_ICCV/images', - # 'output_dir': '/home/lizebin/tensorflow/Detection/MultiNet/RUNS/MultiNet_ICCV'}, - # 'logging': {'display_iter': 50, 'eval_iter': 1000, 'image_iter': 600000, 'save_iter': 5000, 'write_iter': 1000}, - # 'loss_build': {'recombine': True, 'weighted': False, 'weights': [0.7, 2, 0.7]}, - # 'model_list': ['segmentation', 'detection', 'road'], - # 'models': {'detection': '../submodules/KittiBox/hypes/kittiBox.json', - # 'road': '../submodules/KittiClass/hypes/KittiClass_VGG.json', - # 'segmentation': '../submodules/KittiSeg/hypes/KittiVGG.json'}, - # 'path': ['../incl', '../submodules/KittiSeg/incl', '../submodules/KittiBox/incl/', '../submodules/KittiClass/incl/'], - # 'selection': {'random': False, 'use_weights': True, 'weights': [1, 0, 0]}, - # 'solver': {'batch_size': 1, 'max_steps': 100000}} - - #加载模型的各个模块,hypes代表模型的参数文件,modules和submodules[modules]代表模型的组成模块 - for model in meta_hypes['models']: - subhypes[model] = tv_utils.load_hypes_from_logdir(logdir, subdir=model) - hypes = subhypes[model] - # : {'arch': {'deep_feat': 'pool5'}, - # 'augment_level': 1, 'batch_size': 5, 'biggest_box_px': 10000, 'clip_norm': 1.0, - # 'data': {'eval_cmd': '../submodules/KittiObjective2/./evaluate_object2', - # 'label_dir': 'KittiBox/training/label_2', 'train_file': 'KittiBox/train.txt', - # 'truncate_data': False, 'val_file': 'KittiBox/val.txt'}, 'detect_truck': False, - # 'dirs': {'base_path': '/home/mifs/mttt2/github/MultiNet/submodules/KittiBox/hypes', - # 'data_dir': 'DATA', 'image_dir': '/home/lizebin/tensorflow/Detection/MultiNet/RUNS/MultiNet_ICCV/images', - # 'output_dir': '/home/lizebin/tensorflow/Detection/MultiNet/RUNS/MultiNet_ICCV'}, - # 'early_feat_channels': 256, 'focus_size': 1.8, 'grid_height': 12, 'grid_width': 39, - # 'image_height': 384, 'image_width': 1248, - # 'logging': {'display_iter': 200, 'eval_iter': 2000, 'image_iter': 10000, 'save_iter': 2000, - # 'write_iter': 800}, 'model': {'architecture_file': '../encoder/vgg.py', - # 'evaluator_file': '../evals/kitti_eval.py', 'input_file': '../inputs/kitti_input.py', - # 'objective_file': '../decoder/fastBox.py', 'optimizer_file': '../optimizer/generic_optimizer.py'}, - # 'num_classes': 2, 'num_inner_channel': 500, 'path': ['../incl'], 'region_size': 32, - # 'rezoom_change_loss': 'center', 'rezoom_h_coords': [-0.25, 0, 0.25], - # 'rezoom_w_coords': [-0.25, 0, 0.25], 'scale_down': 0.1, - # 'solver': {'batch_size': 1, 'epsilon': 1e-05, 'head_weights': [1.0, 0.1], - # 'hungarian_iou': 0.35, 'learning_rate': 1e-05, 'learning_rate_step': None, - # 'max_steps': 140000, 'opt': 'Adam', 'rnd_seed': 1, 'use_jitter': True, 'weights': ''}, - # 'tau': 0.35, 'use_mask': True, 'use_rezoom': True, 'wd': 0.0005} - hypes['dirs']['output_dir'] = meta_hypes['dirs']['output_dir'] - hypes['dirs']['image_dir'] = meta_hypes['dirs']['image_dir'] - submodules[model] = tv_utils.load_modules_from_logdir(logdir, dirname=model, postfix=model) - - ### dict_keys(['input', 'arch', 'objective', 'solver', 'eval'])加载了这5个模块代表一个模型 - ### submodules[module]代表一个模型的5个模块 - modules = submodules[model] - - return meta_hypes, subhypes, submodules - -def eval_model(logdir, meta_hypes, subhypes, submodules): - first_iter = True - - image_pl = tf.placeholder(tf.float32) - image = tf.expand_dims(image_pl, 0) - image.set_shape([1, 384, 1248, 3]) - - decoded_logits = {} - for model in meta_hypes['models']: - hypes = subhypes[model] ### subhypes[modle]是各个模型的参数文件 - modules = submodules[model] ### submodules[model]是模型的各个组件 - optimizer = modules['solver'] - - with tf.name_scope('Validation_%s' % model): - reuse = {True: False, False: True}[first_iter] - - scope = tf.get_variable_scope() - - with tf.variable_scope(scope, reuse=reuse): - ### inference()函数的输出结果是vgg_dict = {'deep_feat': deep_feat,'early_feat': vgg_fcn.conv4_3} - ### 这里输出的是一个用来计算交叉熵的tensorflow:softmax_linear: Output tensor with the computed logits. - logits = modules['arch'].inference(hypes, image, train=False) - - # """Apply decoder to the logits. - # - # Computation which decode CNN boxes. - # The output can be interpreted as bounding Boxes. - # Args: - # logits: Logits tensor, output von encoder - # - # Return: - # decoded_logits: values which can be interpreted as bounding boxes - # """ - # decoded_logits[model]是一个字典,是对bounding box的预测。dict_keys(['pred_confs_deltas', - # 'pred_boxes_deltas', 'pred_boxes_new', 'pred_boxes', 'pred_logits', 'pred_confidences']) - decoded_logits[model] = modules['objective'].decoder(hypes, logits, train=False) - - first_iter = False - sess = tf.Session() - saver = tf.train.Saver() - - # """ - # Load the weights of a model stored in saver. - # - # Parameters - # ---------- - # checkpoint_dir : str - # The directory of checkpoints. - # sess : tf.Session - # A Session to use to restore the parameters. - # saver : tf.train.Saver - # - # Returns - # ----------- - # int - # training step of checkpoint - # """ - cur_step = core.load_weights(logdir, sess, saver) - - return meta_hypes, subhypes, submodules, decoded_logits, sess, image_pl - -def main(): - logdir = os.path.join("RUNS", "MultiNet_ICCV") - meta_hypes, subhypes, submodules = load_united_model(logdir) ### 从RUN/MultiNet_ICCV下加载模型 - load_out = eval_model(logdir, meta_hypes, subhypes, submodules) - - # Create list of relevant tensors to evaluate - ### meata_hypes是总的参数文件hypes.json; - ### subhypes是各个模型的参数文件; - ### submoudles是各个模型的组成模块; - ### decoded_logits在detection时是bounding box的预测; - ### sesss是会话管理环境; - ### image_pl是图片输入tensor - meta_hypes, subhypes, submodules, decoded_logits, sess, image_pl = load_out - - seg_softmax = decoded_logits['segmentation']['softmax'] - pred_boxes_new = decoded_logits['detection']['pred_boxes_new'] - pred_confidences = decoded_logits['detection']['pred_confidences'] - if len(meta_hypes['model_list']) == 3: - road_softmax = decoded_logits['road']['softmax'][0] - else: - road_softmax = None - - eval_list = [seg_softmax, pred_boxes_new, pred_confidences, road_softmax] - - hypes_road = subhypes['road'] - image = cv2.imread(FLAGS.input) - shape = image.shape - image_height = hypes_road['jitter']['image_height'] - image_width = hypes_road['jitter']['image_width'] - assert (image_height >= shape[0]) - assert (image_width >= shape[1]) - image = cv2.resize(image, (image_height, image_width), interpolation=cv2.INTER_CUBIC) - - ### Run KittiSeg model on image - ### eval_list = [seg_softmax, pred_boxes_new, pred_confidences, road_softmax] - feed_dict = {image_pl: image} - output = sess.run(eval_list, feed_dict=feed_dict) - seg_softmax, pred_boxes_new, pred_confidences, road_softmax = output - - # Create Segmentation Overlay - # """ - # Overlay input_image with a hard segmentation result for two classes. - # Store the result with the same name as segmentation_image, but with - # `-overlay`. - # - # Parameters - # ---------- - # input_image : numpy.array - # An image of shape [width, height, 3]. - # segmentation : numpy.array - # Segmentation of shape [width, height]. - # color: color for forground class - # - # Returns - # ------- - # numpy.array - # The image overlayed with the segmenation - # """ - shape = image.shape - seg_softmax = seg_softmax[:, 1].reshape(shape[0], shape[1]) - hard = seg_softmax > 0.5 - overlay_image = tv_utils.fast_overlay(image, hard) - - # Draw Detection Boxes - new_img, rects = dec_utils.add_rectangles( - subhypes['detection'], [overlay_image], pred_confidences, - pred_boxes_new, show_removed=False, - use_stitching=True, rnn_len=subhypes['detection']['rnn_len'], - min_conf=0.50, tau=subhypes['detection']['tau']) - - # Draw road classification - highway = (np.argmax(road_softmax) == 1) - new_img = road_draw(new_img, highway) - - ### 在终端上打印出预测的结果:检测到的车辆数; - ### Printing some more output information - ### removing predictions <= threshold - ### Printing coordinates of predicted rects. - logging.info("") - threshold = 0.5 - accepted_predictions = [] - for rect in rects: - if rect.score >= threshold: - accepted_predictions.append(rect) - print('') - logging.info("{} Cars detected".format(len(accepted_predictions))) - for i, rect in enumerate(accepted_predictions): - logging.info("") - logging.info("Coordinates of Box {}".format(i)) - logging.info(" x1: {}".format(rect.x1)) - logging.info(" x2: {}".format(rect.x2)) - logging.info(" y1: {}".format(rect.y1)) - logging.info(" y2: {}".format(rect.y2)) - logging.info(" Confidence: {}".format(rect.score)) - if len(meta_hypes['model_list']) == 3: - logging.info("Raw Classification Softmax outputs are: {}" - .format(output[0][0])) - - # Save output image file - if FLAGS.output is None: - output_base_name = FLAGS.input - out_image_name = output_base_name.split('.')[0] + '_out.png' - else: - out_image_name = FLAGS.output - cv2.imwrite(out_image_name, new_img) - - logging.info("") - logging.info("Output image has been saved to: {}".format(os.path.realpath(out_image_name))) - logging.info("") - logging.warning("Do NOT use this Code to evaluate multiple images.") - logging.warning("Demo.py is **very slow** and designed " - "to be a tutorial to show how the MultiNet works.") - logging.warning("") - logging.warning("Please see this comment, if you like to apply demo.py to multiple images see:") - logging.warning("https://github.com/MarvinTeichmann/KittiBox/issues/15#issuecomment-301800058") - - exit(0) - -if __name__ == '__main__': - main() \ No newline at end of file