clement-w commited on
Commit
7a312f9
1 Parent(s): d31975c

First version

Browse files
.gitattributes CHANGED
@@ -32,3 +32,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
32
  *.zip filter=lfs diff=lfs merge=lfs -text
33
  *.zst filter=lfs diff=lfs merge=lfs -text
34
  *tfevents* filter=lfs diff=lfs merge=lfs -text
35
+ *.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
app.py CHANGED
@@ -1,7 +1,188 @@
 
 
 
1
  import gradio as gr
 
 
2
 
3
- def greet(name):
4
- return "Hello " + name + "!!"
 
 
5
 
6
- iface = gr.Interface(fn=greet, inputs="text", outputs="text")
7
- iface.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pathlib
2
+ import validators
3
+ import requests
4
  import gradio as gr
5
+ # For running inference on the TF-Hub module.
6
+ import tensorflow as tf
7
 
8
+ # For downloading the image.
9
+ import matplotlib.pyplot as plt
10
+ import tempfile
11
+ from six import BytesIO
12
 
13
+ # For drawing onto the image.
14
+ import numpy as np
15
+ from PIL import Image
16
+ from PIL import ImageColor
17
+ from PIL import ImageDraw
18
+ from PIL import ImageFont
19
+ from PIL import ImageOps
20
+
21
+ print("load model...")
22
+ detector = tf.saved_model.load("model")
23
+
24
+
25
+ def draw_bounding_box_on_image(image,
26
+ ymin,
27
+ xmin,
28
+ ymax,
29
+ xmax,
30
+ color,
31
+ font,
32
+ thickness=4,
33
+ display_str_list=()):
34
+ """Adds a bounding box to an image."""
35
+ draw = ImageDraw.Draw(image)
36
+ im_width, im_height = image.size
37
+ (left, right, top, bottom) = (xmin * im_width, xmax * im_width,
38
+ ymin * im_height, ymax * im_height)
39
+ draw.line([(left, top), (left, bottom), (right, bottom), (right, top),
40
+ (left, top)],
41
+ width=thickness,
42
+ fill=color)
43
+
44
+ # If the total height of the display strings added to the top of the bounding
45
+ # box exceeds the top of the image, stack the strings below the bounding box
46
+ # instead of above.
47
+ display_str_heights = [font.getsize(ds)[1] for ds in display_str_list]
48
+ # Each display_str has a top and bottom margin of 0.05x.
49
+ total_display_str_height = (1 + 2 * 0.05) * sum(display_str_heights)
50
+
51
+ if top > total_display_str_height:
52
+ text_bottom = top
53
+ else:
54
+ text_bottom = top + total_display_str_height
55
+ # Reverse list and print from bottom to top.
56
+ for display_str in display_str_list[::-1]:
57
+ text_width, text_height = font.getsize(display_str)
58
+ margin = np.ceil(0.05 * text_height)
59
+ draw.rectangle([(left, text_bottom - text_height - 2 * margin),
60
+ (left + text_width, text_bottom)],
61
+ fill=color)
62
+ draw.text((left + margin, text_bottom - text_height - margin),
63
+ display_str,
64
+ fill="black",
65
+ font=font)
66
+ text_bottom -= text_height - 2 * margin
67
+
68
+
69
+ """Overlay labeled boxes on an image with formatted scores and label names."""
70
+
71
+
72
+ def draw_boxes(image, boxes, class_names, scores, max_boxes=10, min_score=0.1):
73
+ colors = list(ImageColor.colormap.values())
74
+
75
+ try:
76
+ font = ImageFont.truetype("/usr/share/fonts/truetype/liberation/LiberationSansNarrow-Regular.ttf",
77
+ 25)
78
+ except IOError:
79
+ print("Font not found, using default font.")
80
+ font = ImageFont.load_default()
81
+
82
+ for i in range(min(boxes.shape[0], max_boxes)):
83
+ if scores[i][0] >= min_score:
84
+ ymin, xmin, ymax, xmax = tuple(boxes[i][0])
85
+ display_str = "{}: {}%".format(class_names[i],
86
+ int(100 * scores[i][0]))
87
+ color = colors[hash(class_names[i]) % len(colors)]
88
+ image_pil = Image.fromarray(np.uint8(image)).convert("RGB")
89
+ draw_bounding_box_on_image(
90
+ image_pil,
91
+ ymin,
92
+ xmin,
93
+ ymax,
94
+ xmax,
95
+ color,
96
+ font,
97
+ display_str_list=[display_str])
98
+ np.copyto(image, np.array(image_pil))
99
+ return image
100
+
101
+
102
+ def run_detector(url_input, image_input, minscore=0.1):
103
+
104
+ if (validators.url(url_input)):
105
+ img = Image.open(requests.get(url_input, stream=True).raw)
106
+ elif (image_input):
107
+ img = image_input
108
+
109
+ converted_img = tf.image.convert_image_dtype(img, tf.uint8)[
110
+ tf.newaxis, ...]
111
+ result = detector(converted_img)
112
+
113
+ result = {key: value.numpy() for key, value in result.items()}
114
+
115
+ print("Found %d objects." % len(result["detection_scores"]))
116
+ labels = ["cyclist" for _ in range(len(result["detection_scores"]))]
117
+ print(labels)
118
+
119
+ image_with_boxes = draw_boxes(
120
+ np.array(img), result["detection_boxes"],
121
+ labels, result["detection_scores"], min_score=minscore)
122
+
123
+ return image_with_boxes
124
+
125
+
126
+ css = '''
127
+ h1#title {
128
+ text-align: center;
129
+ }
130
+ '''
131
+ demo = gr.Blocks(css=css)
132
+
133
+ title = """<h1 id="title">Custom Cyclists detector</h1>"""
134
+ description = "todo"
135
+
136
+
137
+ def set_example_image(example: list) -> dict:
138
+ return gr.Image.update(value=example[0])
139
+
140
+
141
+ def set_example_url(example: list) -> dict:
142
+ return gr.Textbox.update(value=example[0])
143
+
144
+
145
+ urls = ["https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/cyclist-on-path-by-sea-royalty-free-image-1656931301.jpg?crop=0.727xw:0.699xh;0.134xw,0.169xh&resize=640:*"]
146
+
147
+ with demo:
148
+ gr.Markdown(title)
149
+ gr.Markdown(description)
150
+ slider_input = gr.Slider(minimum=0.0, maximum=1,
151
+ value=0.2, label='Prediction Threshold')
152
+
153
+ with gr.Tabs():
154
+ with gr.TabItem('Image URL'):
155
+ with gr.Row():
156
+ url_input = gr.Textbox(
157
+ lines=2, label='Enter valid image URL here..')
158
+ img_output_from_url = gr.Image(shape=(640, 640))
159
+
160
+ with gr.Row():
161
+ example_url = gr.Dataset(components=[url_input], samples=[
162
+ [str(url)] for url in urls])
163
+
164
+ url_but = gr.Button('Detect')
165
+
166
+ with gr.TabItem('Image Upload'):
167
+ with gr.Row():
168
+ img_input = gr.Image(type='pil')
169
+ img_output_from_upload = gr.Image(shape=(650, 650))
170
+
171
+ with gr.Row():
172
+ example_images = gr.Dataset(components=[img_input],
173
+ samples=[[path.as_posix()]
174
+ for path in sorted(pathlib.Path('images').rglob('*.jpg'))])
175
+
176
+ img_but = gr.Button('Detect')
177
+
178
+ url_but.click(run_detector, inputs=[
179
+ url_input, img_input, slider_input], outputs=img_output_from_url, queue=True)
180
+ img_but.click(run_detector, inputs=[
181
+ url_input, img_input, slider_input], outputs=img_output_from_upload, queue=True)
182
+ example_images.click(fn=set_example_image, inputs=[
183
+ example_images], outputs=[img_input])
184
+ example_url.click(fn=set_example_url, inputs=[
185
+ example_url], outputs=[url_input])
186
+
187
+
188
+ demo.launch(enable_queue=True)
images/velo.jpg ADDED
model/pipeline.config ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model {
2
+ ssd {
3
+ num_classes: 1
4
+ image_resizer {
5
+ keep_aspect_ratio_resizer {
6
+ min_dimension: 640
7
+ max_dimension: 640
8
+ pad_to_max_dimension: true
9
+ }
10
+ }
11
+ feature_extractor {
12
+ type: "ssd_efficientnet-b1_bifpn_keras"
13
+ conv_hyperparams {
14
+ regularizer {
15
+ l2_regularizer {
16
+ weight: 4e-05
17
+ }
18
+ }
19
+ initializer {
20
+ truncated_normal_initializer {
21
+ mean: 0.0
22
+ stddev: 0.03
23
+ }
24
+ }
25
+ activation: SWISH
26
+ batch_norm {
27
+ decay: 0.99
28
+ scale: true
29
+ epsilon: 0.001
30
+ }
31
+ force_use_bias: true
32
+ }
33
+ bifpn {
34
+ min_level: 3
35
+ max_level: 7
36
+ num_iterations: 4
37
+ num_filters: 88
38
+ }
39
+ }
40
+ box_coder {
41
+ faster_rcnn_box_coder {
42
+ y_scale: 1.0
43
+ x_scale: 1.0
44
+ height_scale: 1.0
45
+ width_scale: 1.0
46
+ }
47
+ }
48
+ matcher {
49
+ argmax_matcher {
50
+ matched_threshold: 0.5
51
+ unmatched_threshold: 0.5
52
+ ignore_thresholds: false
53
+ negatives_lower_than_unmatched: true
54
+ force_match_for_each_row: true
55
+ use_matmul_gather: true
56
+ }
57
+ }
58
+ similarity_calculator {
59
+ iou_similarity {
60
+ }
61
+ }
62
+ box_predictor {
63
+ weight_shared_convolutional_box_predictor {
64
+ conv_hyperparams {
65
+ regularizer {
66
+ l2_regularizer {
67
+ weight: 4e-05
68
+ }
69
+ }
70
+ initializer {
71
+ random_normal_initializer {
72
+ mean: 0.0
73
+ stddev: 0.01
74
+ }
75
+ }
76
+ activation: SWISH
77
+ batch_norm {
78
+ decay: 0.99
79
+ scale: true
80
+ epsilon: 0.001
81
+ }
82
+ force_use_bias: true
83
+ }
84
+ depth: 88
85
+ num_layers_before_predictor: 3
86
+ kernel_size: 3
87
+ class_prediction_bias_init: -4.6
88
+ use_depthwise: true
89
+ }
90
+ }
91
+ anchor_generator {
92
+ multiscale_anchor_generator {
93
+ min_level: 3
94
+ max_level: 7
95
+ anchor_scale: 4.0
96
+ aspect_ratios: 1.0
97
+ aspect_ratios: 2.0
98
+ aspect_ratios: 0.5
99
+ scales_per_octave: 3
100
+ }
101
+ }
102
+ post_processing {
103
+ batch_non_max_suppression {
104
+ score_threshold: 1e-08
105
+ iou_threshold: 0.5
106
+ max_detections_per_class: 100
107
+ max_total_detections: 100
108
+ }
109
+ score_converter: SIGMOID
110
+ }
111
+ normalize_loss_by_num_matches: true
112
+ loss {
113
+ localization_loss {
114
+ weighted_smooth_l1 {
115
+ }
116
+ }
117
+ classification_loss {
118
+ weighted_sigmoid_focal {
119
+ gamma: 1.5
120
+ alpha: 0.25
121
+ }
122
+ }
123
+ classification_weight: 1.0
124
+ localization_weight: 1.0
125
+ }
126
+ encode_background_as_zeros: true
127
+ normalize_loc_loss_by_codesize: true
128
+ inplace_batchnorm_update: true
129
+ freeze_batchnorm: false
130
+ add_background_class: false
131
+ }
132
+ }
133
+ train_config {
134
+ batch_size: 3
135
+ data_augmentation_options {
136
+ random_horizontal_flip {
137
+ probability: 0.3
138
+ }
139
+ }
140
+ data_augmentation_options {
141
+ random_scale_crop_and_pad_to_square {
142
+ output_size: 640
143
+ scale_min: 0.1
144
+ scale_max: 2.0
145
+ }
146
+ }
147
+ data_augmentation_options {
148
+ random_distort_color {
149
+ color_ordering: 1
150
+ }
151
+ }
152
+ sync_replicas: true
153
+ optimizer {
154
+ momentum_optimizer {
155
+ learning_rate {
156
+ cosine_decay_learning_rate {
157
+ learning_rate_base: 0.02
158
+ total_steps: 300000
159
+ warmup_learning_rate: 0.001
160
+ warmup_steps: 2500
161
+ }
162
+ }
163
+ momentum_optimizer_value: 0.9
164
+ }
165
+ use_moving_average: false
166
+ }
167
+ fine_tune_checkpoint: "pre-trained-models/efficientdet_d1_coco17_tpu-32/checkpoint/ckpt-0"
168
+ num_steps: 300000
169
+ startup_delay_steps: 0.0
170
+ replicas_to_aggregate: 8
171
+ max_number_of_boxes: 100
172
+ unpad_groundtruth_tensors: false
173
+ fine_tune_checkpoint_type: "detection"
174
+ use_bfloat16: false
175
+ fine_tune_checkpoint_version: V2
176
+ }
177
+ train_input_reader {
178
+ label_map_path: "annotations/label_map.pbtxt"
179
+ tf_record_input_reader {
180
+ input_path: "annotations/train.record"
181
+ }
182
+ }
183
+ eval_config {
184
+ metrics_set: "coco_detection_metrics"
185
+ use_moving_averages: false
186
+ batch_size: 1
187
+ }
188
+ eval_input_reader {
189
+ label_map_path: "annotations/label_map.pbtxt"
190
+ shuffle: true
191
+ num_epochs: 1
192
+ tf_record_input_reader {
193
+ input_path: "annotations/validation.record"
194
+ }
195
+ }
model/saved_model/saved_model.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a8935bf4db280c457ea008e4f1f86463d8d9f6c6ae4320b3a30150859c3c298f
3
+ size 22291244
model/saved_model/variables/variables.data-00000-of-00001 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1da925cefb226e8bccd26e171f658e4f237cb96e0e576db580e3c13c81d369c9
3
+ size 33885404
model/saved_model/variables/variables.index ADDED
Binary file (50.5 kB). View file