a b/Object-Detection/object_detection.py
1
#!/usr/bin/env python
2
# coding: utf-8
3
4
# # Object Detection Demo
5
# Welcome to the object detection inference walkthrough!  This notebook will walk you step by step through the process of using a pre-trained model to detect objects in an image. Make sure to follow the [installation instructions](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/installation.md) before you start.
6
7
# # Imports
8
9
# In[ ]:
10
11
12
import numpy as np
13
import os
14
import sys
15
import tensorflow as tf
16
from tensorflow.keras import backend as K
17
import pickle
18
19
# for download url and extract zip
20
# import six.moves.urllib as urllib
21
# import tarfile
22
# import zipfile
23
24
# legacy utils
25
# from collections import defaultdict
26
# from io import StringIO
27
28
from matplotlib import pyplot as plt
29
from PIL import Image
30
31
# zhulei custom config patch
32
config = tf.ConfigProto()
33
config.gpu_options.allow_growth = True  # dynamically grow the memory used on the GPU
34
sess = tf.Session(config=config)
35
K.set_session(sess)  # set this TensorFlow session as the default session for Keras
36
37
# This is needed since the notebook is stored in the object_detection folder.
38
sys.path.append("..")
39
from object_detection.utils import ops as utils_ops
40
41
print(tf.__version__)
42
43
44
# ## Env setup
45
46
# In[ ]:
47
48
49
myhost = os.uname()[1]
50
print(">>>>    Hostname: ", myhost)
51
print("\nCWD: ", os.getcwd())
52
53
54
# ## Object detection imports
55
# Here are the imports from the object detection module.
56
57
# In[ ]:
58
59
60
from utils import label_map_util
61
62
from utils import visualization_utils as vis_util
63
64
65
# # Model preparation 
66
67
# ## Variables
68
# 
69
# Any model exported using the `export_inference_graph.py` tool can be loaded here simply by changing `PATH_TO_CKPT` to point to a new .pb file.  
70
# 
71
# By default we use an "SSD with Mobilenet" model here. See the [detection model zoo](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md) for a list of other models that can be run out-of-the-box with varying speeds and accuracies.
72
73
# In[ ]:
74
75
76
# Folder name containing the Trained Obj-det model/graph
77
MODEL_NAME = 'Axial_1-491_Resnet_Jun142020_graph'
78
79
# Path to frozen detection graph. This is the actual model that is used for the object detection.
80
PATH_TO_CKPT = MODEL_NAME + '/frozen_inference_graph.pb'
81
82
# List of the strings that is used to add correct label for each box.
83
PATH_TO_LABELS = os.path.join('training', 'ak_detection.pbtxt')
84
85
86
# 3 for axial, 1 for sagittal
87
NUM_CLASSES = 3
88
89
# save previews of the overlay images
90
save_previews = False
91
92
if save_previews:
93
    script_dir = os.getcwd()
94
    results_dir = os.path.join(script_dir, 'Sag_Resnet_1-491-preview_obj-det-results-Jun222020/')
95
96
    if not os.path.isdir(results_dir):
97
        os.makedirs(results_dir)
98
99
# ## Load a (frozen) Tensorflow model into memory.
100
101
# In[ ]:
102
103
104
# zhulei updated with compat.v1 and tf.io
105
detection_graph = tf.Graph()
106
with detection_graph.as_default():
107
    od_graph_def = tf.compat.v1.GraphDef()
108
    with tf.io.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
109
        serialized_graph = fid.read()
110
        od_graph_def.ParseFromString(serialized_graph)
111
        tf.import_graph_def(od_graph_def, name='')
112
113
114
115
label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
116
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
117
category_index = label_map_util.create_category_index(categories)
118
# zhulei custom modify
119
#category_index = {1: {'id': 1, 'name': 'left'}, 2: {'id': 2, 'name': 'center'}, 3: {'id': 3, 'name': 'right'}}
120
print("\ncategory_index: ", category_index)
121
122
123
# ## Helper code
124
125
# In[ ]:
126
127
128
# zhulei modify to detect image.mode
129
def load_image_into_numpy_array(image):
130
    (im_width, im_height) = image.size
131
    # 'L' for Grayscale, 'RGB' : for 3 channel images
132
    channel_dict = {'L':1, 'RGB':3}
133
    return np.array(image.getdata()).reshape(
134
        (im_height, im_width, channel_dict[image.mode])).astype(np.uint8)
135
136
137
# # Detection
138
139
# In[ ]:
140
141
142
print("current dir: ", os.getcwd())
143
144
# If you want to test the code with your images, just add path to the images to the TEST_IMAGE_PATHS.
145
PATH_TO_TEST_IMAGES_DIR = 'images/test'
146
147
148
generated_pickle = './{}/obj-det.pickle'.format(
149
    PATH_TO_TEST_IMAGES_DIR)
150
151
# TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'image{}.jpg'.format(i)) for i in range(1, 3) ]
152
TEST_IMAGE_PATHS = []
153
for file in os.listdir(PATH_TO_TEST_IMAGES_DIR):
154
    if '.jpg' in file or '.png' in file or '.JPG' in file:
155
        TEST_IMAGE_PATHS.append(os.path.join(PATH_TO_TEST_IMAGES_DIR, file))
156
157
# Size, in inches, of the output images.
158
IMAGE_SIZE = (12, 8)
159
160
print("\nTest images: ", TEST_IMAGE_PATHS[:5])
161
162
print("\nNum test images: ", len(TEST_IMAGE_PATHS))
163
164
165
# In[ ]:
166
167
168
def run_inference_for_single_image(image, graph):
169
  with graph.as_default():
170
    with tf.compat.v1.Session() as sess:
171
      # Get handles to input and output tensors
172
      ops = tf.compat.v1.get_default_graph().get_operations()
173
      all_tensor_names = {output.name for op in ops for output in op.outputs}
174
      tensor_dict = {}
175
      for key in [
176
          'num_detections', 'detection_boxes', 'detection_scores',
177
          'detection_classes', 'detection_masks'
178
      ]:
179
        tensor_name = key + ':0'
180
        if tensor_name in all_tensor_names:
181
          tensor_dict[key] = tf.compat.v1.get_default_graph().get_tensor_by_name(
182
              tensor_name)
183
      if 'detection_masks' in tensor_dict:
184
        # The following processing is only for single image
185
        detection_boxes = tf.squeeze(tensor_dict['detection_boxes'], [0])
186
        detection_masks = tf.squeeze(tensor_dict['detection_masks'], [0])
187
        # Reframe is required to translate mask from box coordinates to image coordinates and fit the image size.
188
        real_num_detection = tf.cast(tensor_dict['num_detections'][0], tf.int32)
189
        detection_boxes = tf.slice(detection_boxes, [0, 0], [real_num_detection, -1])
190
        detection_masks = tf.slice(detection_masks, [0, 0, 0], [real_num_detection, -1, -1])
191
        detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(
192
            detection_masks, detection_boxes, image.shape[0], image.shape[1])
193
        detection_masks_reframed = tf.cast(
194
            tf.greater(detection_masks_reframed, 0.5), tf.uint8)
195
        # Follow the convention by adding back the batch dimension
196
        tensor_dict['detection_masks'] = tf.expand_dims(
197
            detection_masks_reframed, 0)
198
      image_tensor = tf.compat.v1.get_default_graph().get_tensor_by_name('image_tensor:0')
199
200
      # Run inference
201
      output_dict = sess.run(tensor_dict,
202
                             feed_dict={image_tensor: np.expand_dims(image, 0)})
203
204
      # all outputs are float32 numpy arrays, so convert types as appropriate
205
      output_dict['num_detections'] = int(output_dict['num_detections'][0])
206
      output_dict['detection_classes'] = output_dict[
207
          'detection_classes'][0].astype(np.uint8)
208
      output_dict['detection_boxes'] = output_dict['detection_boxes'][0]
209
      output_dict['detection_scores'] = output_dict['detection_scores'][0]
210
      if 'detection_masks' in output_dict:
211
        output_dict['detection_masks'] = output_dict['detection_masks'][0]
212
  return output_dict
213
214
215
# In[ ]:
216
217
detection_result = {}
218
219
count_img = 0
220
221
for image_path in TEST_IMAGE_PATHS:
222
    # zhulei add counting img
223
    print('process: ', str(count_img), image_path)
224
    count_img += 1
225
226
    image = Image.open(image_path)
227
    # the array based representation of the image will be used later in order to prepare the
228
    # result image with boxes and labels on it.
229
    image_np = load_image_into_numpy_array(image)
230
231
    # zhulei check for image_np
232
    if image_np.shape[2] != 3:
233
        # Duplicating the Content
234
        image_np = np.broadcast_to(image_np, (image_np.shape[0], image_np.shape[1], 3)).copy()
235
        ## adding Zeros to other Channels
236
        ## This adds Red Color stuff in background -- not recommended
237
        # z = np.zeros(image_np.shape[:-1] + (2,), dtype=image_np.dtype)
238
        # image_np = np.concatenate((image_np, z), axis=-1)
239
    
240
    # Expand dimensions since the model expects images to have shape: [1, None, None, 3]
241
    image_np_expanded = np.expand_dims(image_np, axis=0)
242
    # Actual detection.
243
    output_dict = run_inference_for_single_image(image_np, detection_graph)
244
    
245
    # Visualization of the results of a detection.
246
    vis_util.visualize_boxes_and_labels_on_image_array(
247
      image_np,
248
      output_dict['detection_boxes'],
249
      output_dict['detection_classes'],
250
      output_dict['detection_scores'],
251
      category_index,
252
      instance_masks=output_dict.get('detection_masks'),
253
      use_normalized_coordinates=True,
254
      line_thickness=2)  # default 8
255
256
    # zhulei custom
257
    boxes = output_dict['detection_boxes']
258
    classes = output_dict['detection_classes']
259
    scores = output_dict['detection_scores']
260
    max_boxes_to_draw = 20
261
    min_score_thresh = 0.5
262
    box_to_class = {}
263
264
    # zhulei custom noting down the box_to_classes
265
    for i in range(min(max_boxes_to_draw, boxes.shape[0])):
266
        if scores[i] > min_score_thresh:
267
            box = tuple(boxes[i].tolist())
268
            box_to_class[box] = classes[i]
269
270
    # for export to pickle later
271
    detection_result[image_path] = box_to_class
272
273
    if save_previews:
274
        plt.figure(figsize=IMAGE_SIZE)
275
        # need imshow to save the imgs
276
        plt.imshow(image_np)
277
        plt.savefig('{}/{}'.format(
278
            results_dir, os.path.basename(image_path))
279
        )
280
281
# In[ ]:
282
283
# export detection_result dict with pickle
284
with open(generated_pickle, 'wb') as f:
285
    pickle.dump(detection_result, f, protocol=pickle.HIGHEST_PROTOCOL)
286
287
288
# verify the generated pickle is saved
289
# generated_pickle = './{}/{}_detection.pickle'.format(PATH_TO_TEST_IMAGES_DIR, labeler)
290
print(os.path.exists(generated_pickle))
291
print(generated_pickle, "exists")
292
print(os.path.getsize(generated_pickle), "byte")