Skip to content

Commit b9459d8

Browse files
authored
Merge pull request #30 from developmentseed/tf_object_detection
tf records generation from labels.npz
2 parents 4e8774f + f0da160 commit b9459d8

10 files changed

+642
-0
lines changed

examples/images/preview_tiles.jpg

86.5 KB
Loading

examples/images/tensorboard_sc.jpg

396 KB
Loading

examples/images/tf_od_result.jpg

85.2 KB
Loading

examples/images/tf_sc.jpg

236 KB
Loading

examples/images/tf_tiles.jpg

14.2 KB
Loading

examples/utils/building_od.pbtxt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
item {
2+
id: 1
3+
name: 'building'
4+
}
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
# SSD with Inception v2 configuration for MSCOCO Dataset.
2+
# Users should configure the fine_tune_checkpoint field in the train config as
3+
# well as the label_map_path and input_path fields in the train_input_reader and
4+
# eval_input_reader. Search for "PATH_TO_BE_CONFIGURED" to find the fields that
5+
# should be configured.
6+
7+
model {
8+
ssd {
9+
num_classes: 90
10+
box_coder {
11+
faster_rcnn_box_coder {
12+
y_scale: 10.0
13+
x_scale: 10.0
14+
height_scale: 5.0
15+
width_scale: 5.0
16+
}
17+
}
18+
matcher {
19+
argmax_matcher {
20+
matched_threshold: 0.5
21+
unmatched_threshold: 0.5
22+
ignore_thresholds: false
23+
negatives_lower_than_unmatched: true
24+
force_match_for_each_row: true
25+
}
26+
}
27+
similarity_calculator {
28+
iou_similarity {
29+
}
30+
}
31+
anchor_generator {
32+
ssd_anchor_generator {
33+
num_layers: 6
34+
min_scale: 0.2
35+
max_scale: 0.95
36+
aspect_ratios: 1.0
37+
aspect_ratios: 2.0
38+
aspect_ratios: 0.5
39+
aspect_ratios: 3.0
40+
aspect_ratios: 0.3333
41+
reduce_boxes_in_lowest_layer: true
42+
}
43+
}
44+
image_resizer {
45+
fixed_shape_resizer {
46+
height: 300
47+
width: 300
48+
}
49+
}
50+
box_predictor {
51+
convolutional_box_predictor {
52+
min_depth: 0
53+
max_depth: 0
54+
num_layers_before_predictor: 0
55+
use_dropout: false
56+
dropout_keep_probability: 0.8
57+
kernel_size: 3
58+
box_code_size: 4
59+
apply_sigmoid_to_scores: false
60+
conv_hyperparams {
61+
activation: RELU_6,
62+
regularizer {
63+
l2_regularizer {
64+
weight: 0.00004
65+
}
66+
}
67+
initializer {
68+
truncated_normal_initializer {
69+
stddev: 0.03
70+
mean: 0.0
71+
}
72+
}
73+
}
74+
}
75+
}
76+
feature_extractor {
77+
type: 'ssd_inception_v2'
78+
min_depth: 16
79+
depth_multiplier: 1.0
80+
conv_hyperparams {
81+
activation: RELU_6,
82+
regularizer {
83+
l2_regularizer {
84+
weight: 0.00004
85+
}
86+
}
87+
initializer {
88+
truncated_normal_initializer {
89+
stddev: 0.03
90+
mean: 0.0
91+
}
92+
}
93+
batch_norm {
94+
train: true,
95+
scale: true,
96+
center: true,
97+
decay: 0.9997,
98+
epsilon: 0.001,
99+
}
100+
}
101+
}
102+
loss {
103+
classification_loss {
104+
weighted_sigmoid {
105+
anchorwise_output: true
106+
}
107+
}
108+
localization_loss {
109+
weighted_smooth_l1 {
110+
anchorwise_output: true
111+
}
112+
}
113+
hard_example_miner {
114+
num_hard_examples: 3000
115+
iou_threshold: 0.99
116+
loss_type: CLASSIFICATION
117+
max_negatives_per_positive: 3
118+
min_negatives_per_image: 0
119+
}
120+
classification_weight: 1.0
121+
localization_weight: 1.0
122+
}
123+
normalize_loss_by_num_matches: true
124+
post_processing {
125+
batch_non_max_suppression {
126+
score_threshold: 1e-8
127+
iou_threshold: 0.6
128+
max_detections_per_class: 100
129+
max_total_detections: 100
130+
}
131+
score_converter: SIGMOID
132+
}
133+
}
134+
}
135+
136+
train_config: {
137+
batch_size: 24
138+
optimizer {
139+
rms_prop_optimizer: {
140+
learning_rate: {
141+
exponential_decay_learning_rate {
142+
initial_learning_rate: 0.004
143+
decay_steps: 800720
144+
decay_factor: 0.95
145+
}
146+
}
147+
momentum_optimizer_value: 0.9
148+
decay: 0.9
149+
epsilon: 1.0
150+
}
151+
}
152+
fine_tune_checkpoint: "ssd_inception_v2_coco_2017_11_17/model.ckpt"
153+
from_detection_checkpoint: true
154+
# Note: The below line limits the training process to 200K steps, which we
155+
# empirically found to be sufficient enough to train the pets dataset. This
156+
# effectively bypasses the learning rate schedule (the learning rate will
157+
# never decay). Remove the below line to train indefinitely.
158+
num_steps: 200000
159+
data_augmentation_options {
160+
random_horizontal_flip {
161+
}
162+
}
163+
data_augmentation_options {
164+
ssd_random_crop {
165+
}
166+
}
167+
}
168+
169+
train_input_reader: {
170+
tf_record_input_reader {
171+
input_path: "data/train_buildings.record"
172+
}
173+
label_map_path: "data/building_od.pbtxt"
174+
}
175+
176+
eval_config: {
177+
num_examples: 8000
178+
# Note: The below line limits the evaluation process to 10 evaluations.
179+
# Remove the below line to evaluate indefinitely.
180+
max_evals: 10
181+
}
182+
183+
eval_input_reader: {
184+
tf_record_input_reader {
185+
input_path: "data/test_buildings.record"
186+
}
187+
label_map_path: "data/building_od.pbtxt"
188+
shuffle: false
189+
num_readers: 1
190+
num_epochs: 1
191+
}

examples/utils/tf_od_predict.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
"""
2+
This is adapted from Tensorflow (https://github.com/tensorflow/models/tree/master/research/object_detection);
3+
Save this code under the directory `models/research/object_detection/`
4+
5+
To use, run:
6+
python tf_od_predict.py --model_name=building_od_ssd \
7+
--path_to_label=data/building_od.pbtxt \
8+
--test_image_path=test_images
9+
"""
10+
11+
import os
12+
from os import makedirs, path as op
13+
import sys
14+
import glob
15+
import six.moves.urllib as urllib
16+
import tensorflow as tf
17+
import tarfile
18+
19+
from io import StringIO
20+
import zipfile
21+
import numpy as np
22+
from collections import defaultdict
23+
from matplotlib import pyplot as plt
24+
from PIL import ImageDraw, Image
25+
26+
sys.path.append("..")
27+
28+
from utils import label_map_util
29+
from utils import visualization_utils as vis_util
30+
31+
flags = tf.app.flags
32+
flags.DEFINE_string('model_name', '', 'Path to frozen detection graph')
33+
flags.DEFINE_string('path_to_label', '', 'Path to label file')
34+
flags.DEFINE_string('test_image_path', '', 'Path to test imgs and output diractory')
35+
FLAGS = flags.FLAGS
36+
37+
def load_image_into_numpy_array(image):
38+
(im_width, im_height) = image.size
39+
return np.array(image.getdata()).reshape((im_height, im_width, 3)).astype(np.uint8)
40+
41+
def tf_od_pred():
42+
with detection_graph.as_default():
43+
with tf.Session(graph=detection_graph) as sess:
44+
# Definite input and output Tensors for detection_graph
45+
image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
46+
# Each box represents a part of the image where a particular object was detected.
47+
detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
48+
# Each score represent how level of confidence for each of the objects.
49+
# Score is shown on the result image, together with the class label.
50+
detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
51+
detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')
52+
num_detections = detection_graph.get_tensor_by_name('num_detections:0')
53+
for image_path in test_imgs:
54+
image = Image.open(image_path)
55+
image_np = load_image_into_numpy_array(image)
56+
# the array based representation of the image will be used later in order to prepare the
57+
# result image with boxes and labels on it.
58+
# Expand dimensions since the model expects images to have shape: [1, None, None, 3]
59+
image_np_expanded = np.expand_dims(image_np, axis=0)
60+
# Actual detection.
61+
(boxes, scores, classes, num) = sess.run(
62+
[detection_boxes, detection_scores, detection_classes, num_detections],
63+
feed_dict={image_tensor: image_np_expanded})
64+
# draw_bounding_box_on_image(image, boxes, )
65+
# Visualization of the results of a detection.
66+
vis_image = vis_util.visualize_boxes_and_labels_on_image_array(
67+
image_np,
68+
np.squeeze(boxes),
69+
np.squeeze(classes).astype(np.int32),
70+
np.squeeze(scores),
71+
category_index,
72+
use_normalized_coordinates=True,
73+
line_thickness=1)
74+
print("{} boxes in {} image tile!".format(len(boxes), image_path))
75+
image_pil = Image.fromarray(np.uint8(vis_image)).convert('RGB')
76+
with tf.gfile.Open(image_path, 'w') as fid:
77+
image_pil.save(fid, 'PNG')
78+
79+
80+
81+
if __name__ =='__main__':
82+
# load your own trained model inference graph. This inference graph was generated from
83+
# export_inference_graph.py under model directory, see `models/research/object_detection/`
84+
model_name = op.join(os.getcwd(), FLAGS.model_name)
85+
# Path to frozen detection graph.
86+
path_to_ckpt = op.join(model_name, 'frozen_inference_graph.pb')
87+
# Path to the label file
88+
path_to_label = op.join(os.getcwd(), FLAGS.path_to_label)
89+
#only train on buildings
90+
num_classes = 1
91+
#Directory to test images path
92+
test_image_path = op.join(os.getcwd(), FLAGS.test_image_path)
93+
test_imgs = glob.glob(test_image_path + "/*.jpg")
94+
95+
############
96+
#Load the frozen tensorflow model
97+
#############
98+
99+
detection_graph = tf.Graph()
100+
with detection_graph.as_default():
101+
od_graph_def = tf.GraphDef()
102+
with tf.gfile.GFile(path_to_ckpt, 'rb') as fid:
103+
serialized_graph = fid.read()
104+
od_graph_def.ParseFromString(serialized_graph)
105+
tf.import_graph_def(od_graph_def, name='')
106+
107+
############
108+
#Load the label file
109+
#############
110+
label_map = label_map_util.load_labelmap(path_to_label)
111+
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=num_classes, use_display_name=True)
112+
category_index = label_map_util.create_category_index(categories)
113+
tf_od_pred()

0 commit comments

Comments
 (0)