gatesla commited on
Commit
9434aee
1 Parent(s): c17e51b

Added separate file to see how code works without Gradio

Browse files
Files changed (2) hide show
  1. .gitignore +236 -0
  2. image_functions.py +171 -0
.gitignore ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Created by https://www.toptal.com/developers/gitignore/api/python,linux,visualstudiocode,windows
2
+ # Edit at https://www.toptal.com/developers/gitignore?templates=python,linux,visualstudiocode,windows
3
+
4
+ ### Linux ###
5
+ *~
6
+
7
+ # temporary files which can be created if a process still has a handle open of a deleted file
8
+ .fuse_hidden*
9
+
10
+ # KDE directory preferences
11
+ .directory
12
+
13
+ # Linux trash folder which might appear on any partition or disk
14
+ .Trash-*
15
+
16
+ # .nfs files are created when an open file is removed but is still being accessed
17
+ .nfs*
18
+
19
+ ### Python ###
20
+ # Byte-compiled / optimized / DLL files
21
+ __pycache__/
22
+ *.py[cod]
23
+ *$py.class
24
+
25
+ # C extensions
26
+ *.so
27
+
28
+ # Distribution / packaging
29
+ .Python
30
+ build/
31
+ develop-eggs/
32
+ dist/
33
+ downloads/
34
+ eggs/
35
+ .eggs/
36
+ lib/
37
+ lib64/
38
+ parts/
39
+ sdist/
40
+ var/
41
+ wheels/
42
+ share/python-wheels/
43
+ *.egg-info/
44
+ .installed.cfg
45
+ *.egg
46
+ MANIFEST
47
+
48
+ # PyInstaller
49
+ # Usually these files are written by a python script from a template
50
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
51
+ *.manifest
52
+ *.spec
53
+
54
+ # Installer logs
55
+ pip-log.txt
56
+ pip-delete-this-directory.txt
57
+
58
+ # Unit test / coverage reports
59
+ htmlcov/
60
+ .tox/
61
+ .nox/
62
+ .coverage
63
+ .coverage.*
64
+ .cache
65
+ nosetests.xml
66
+ coverage.xml
67
+ *.cover
68
+ *.py,cover
69
+ .hypothesis/
70
+ .pytest_cache/
71
+ cover/
72
+
73
+ # Translations
74
+ *.mo
75
+ *.pot
76
+
77
+ # Django stuff:
78
+ *.log
79
+ local_settings.py
80
+ db.sqlite3
81
+ db.sqlite3-journal
82
+
83
+ # Flask stuff:
84
+ instance/
85
+ .webassets-cache
86
+
87
+ # Scrapy stuff:
88
+ .scrapy
89
+
90
+ # Sphinx documentation
91
+ docs/_build/
92
+
93
+ # PyBuilder
94
+ .pybuilder/
95
+ target/
96
+
97
+ # Jupyter Notebook
98
+ .ipynb_checkpoints
99
+
100
+ # IPython
101
+ profile_default/
102
+ ipython_config.py
103
+
104
+ # pyenv
105
+ # For a library or package, you might want to ignore these files since the code is
106
+ # intended to run in multiple environments; otherwise, check them in:
107
+ # .python-version
108
+
109
+ # pipenv
110
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
111
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
112
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
113
+ # install all needed dependencies.
114
+ #Pipfile.lock
115
+
116
+ # poetry
117
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
118
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
119
+ # commonly ignored for libraries.
120
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
121
+ #poetry.lock
122
+
123
+ # pdm
124
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
125
+ #pdm.lock
126
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
127
+ # in version control.
128
+ # https://pdm.fming.dev/#use-with-ide
129
+ .pdm.toml
130
+
131
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
132
+ __pypackages__/
133
+
134
+ # Celery stuff
135
+ celerybeat-schedule
136
+ celerybeat.pid
137
+
138
+ # SageMath parsed files
139
+ *.sage.py
140
+
141
+ # Environments
142
+ .env
143
+ .venv
144
+ env/
145
+ venv/
146
+ ENV/
147
+ env.bak/
148
+ venv.bak/
149
+
150
+ # Spyder project settings
151
+ .spyderproject
152
+ .spyproject
153
+
154
+ # Rope project settings
155
+ .ropeproject
156
+
157
+ # mkdocs documentation
158
+ /site
159
+
160
+ # mypy
161
+ .mypy_cache/
162
+ .dmypy.json
163
+ dmypy.json
164
+
165
+ # Pyre type checker
166
+ .pyre/
167
+
168
+ # pytype static type analyzer
169
+ .pytype/
170
+
171
+ # Cython debug symbols
172
+ cython_debug/
173
+
174
+ # PyCharm
175
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
176
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
177
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
178
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
179
+ #.idea/
180
+
181
+ ### Python Patch ###
182
+ # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
183
+ poetry.toml
184
+
185
+ # ruff
186
+ .ruff_cache/
187
+
188
+ # LSP config files
189
+ pyrightconfig.json
190
+
191
+ ### VisualStudioCode ###
192
+ .vscode/*
193
+ !.vscode/settings.json
194
+ !.vscode/tasks.json
195
+ !.vscode/launch.json
196
+ !.vscode/extensions.json
197
+ !.vscode/*.code-snippets
198
+
199
+ # Local History for Visual Studio Code
200
+ .history/
201
+
202
+ # Built Visual Studio Code Extensions
203
+ *.vsix
204
+
205
+ ### VisualStudioCode Patch ###
206
+ # Ignore all local history of files
207
+ .history
208
+ .ionide
209
+
210
+ ### Windows ###
211
+ # Windows thumbnail cache files
212
+ Thumbs.db
213
+ Thumbs.db:encryptable
214
+ ehthumbs.db
215
+ ehthumbs_vista.db
216
+
217
+ # Dump file
218
+ *.stackdump
219
+
220
+ # Folder config file
221
+ [Dd]esktop.ini
222
+
223
+ # Recycle Bin used on file shares
224
+ $RECYCLE.BIN/
225
+
226
+ # Windows Installer files
227
+ *.cab
228
+ *.msi
229
+ *.msix
230
+ *.msm
231
+ *.msp
232
+
233
+ # Windows shortcuts
234
+ *.lnk
235
+
236
+ # End of https://www.toptal.com/developers/gitignore/api/python,linux,visualstudiocode,windows
image_functions.py ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import matplotlib.pyplot as plt
3
+ import requests, validators
4
+ import torch
5
+ import pathlib
6
+ from PIL import Image
7
+ from transformers import AutoFeatureExtractor, DetrForObjectDetection, YolosForObjectDetection
8
+ from ultralyticsplus import YOLO, render_result
9
+
10
+ import os
11
+
12
+ # colors for visualization
13
+ COLORS = [
14
+ [0.000, 0.447, 0.741],
15
+ [0.850, 0.325, 0.098],
16
+ [0.929, 0.694, 0.125],
17
+ [0.494, 0.184, 0.556],
18
+ [0.466, 0.674, 0.188],
19
+ [0.301, 0.745, 0.933]
20
+ ]
21
+
22
+ YOLOV8_LABELS = ['pedestrian', 'people', 'bicycle', 'car', 'van', 'truck', 'tricycle', 'awning-tricycle', 'bus', 'motor']
23
+
24
+ def make_prediction(img, feature_extractor, model):
25
+ inputs = feature_extractor(img, return_tensors="pt")
26
+ outputs = model(**inputs)
27
+ img_size = torch.tensor([tuple(reversed(img.size))])
28
+ processed_outputs = feature_extractor.post_process(outputs, img_size)
29
+ return processed_outputs
30
+
31
+ def fig2img(fig):
32
+ buf = io.BytesIO()
33
+ fig.savefig(buf)
34
+ buf.seek(0)
35
+ img = Image.open(buf)
36
+ return img
37
+
38
+
39
+ def visualize_prediction(pil_img, output_dict, threshold=0.7, id2label=None):
40
+ keep = output_dict["scores"] > threshold
41
+ boxes = output_dict["boxes"][keep].tolist()
42
+ scores = output_dict["scores"][keep].tolist()
43
+ labels = output_dict["labels"][keep].tolist()
44
+ if id2label is not None:
45
+ labels = [id2label[x] for x in labels]
46
+
47
+ # print("Labels " + str(labels))
48
+
49
+ plt.figure(figsize=(16, 10))
50
+ plt.imshow(pil_img)
51
+ ax = plt.gca()
52
+ colors = COLORS * 100
53
+ for score, (xmin, ymin, xmax, ymax), label, color in zip(scores, boxes, labels, colors):
54
+ ax.add_patch(plt.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, fill=False, color=color, linewidth=3))
55
+ ax.text(xmin, ymin, f"{label}: {score:0.2f}", fontsize=15, bbox=dict(facecolor="yellow", alpha=0.5))
56
+ plt.axis("off")
57
+ return fig2img(plt.gcf())
58
+
59
+ def detect_objects(model_name,url_input,image_input,threshold):
60
+
61
+
62
+ if 'yolov8' in model_name:
63
+ # Working on getting this to work, another approach
64
+ # https://docs.ultralytics.com/modes/predict/#key-features-of-predict-mode
65
+
66
+ model = YOLO(model_name)
67
+ # set model parameters
68
+ model.overrides['conf'] = 0.15 # NMS confidence threshold
69
+ model.overrides['iou'] = 0.05 # NMS IoU threshold https://www.google.com/search?client=firefox-b-1-d&q=intersection+over+union+meaning
70
+ model.overrides['agnostic_nms'] = False # NMS class-agnostic
71
+ model.overrides['max_det'] = 1000 # maximum number of detections per image
72
+
73
+ results = model.predict(image_input)
74
+
75
+ render = render_result(model=model, image=image_input, result=results[0])
76
+
77
+ final_str = ""
78
+ final_str_abv = ""
79
+ final_str_else = ""
80
+
81
+ for result in results:
82
+ boxes = result.boxes.cpu().numpy()
83
+ for i, box in enumerate(boxes):
84
+ # r = box.xyxy[0].astype(int)
85
+ coordinates = box.xyxy[0].astype(int)
86
+ try:
87
+ label = YOLOV8_LABELS[int(box.cls)]
88
+ except:
89
+ label = "ERROR"
90
+ try:
91
+ confi = float(box.conf)
92
+ except:
93
+ confi = 0.0
94
+ # final_str_abv += str() + "__" + str(box.cls) + "__" + str(box.conf) + "__" + str(box) + "\n"
95
+ if confi >= threshold:
96
+ final_str_abv += f"Detected `{label}` with confidence `{confi}` at location `{coordinates}`\n"
97
+ else:
98
+ final_str_else += f"Detected `{label}` with confidence `{confi}` at location `{coordinates}`\n"
99
+
100
+ final_str = "{:*^50}\n".format("ABOVE THRESHOLD OR EQUAL") + final_str_abv + "\n{:*^50}\n".format("BELOW THRESHOLD")+final_str_else
101
+
102
+ return render, final_str
103
+ else:
104
+
105
+ #Extract model and feature extractor
106
+ feature_extractor = AutoFeatureExtractor.from_pretrained(model_name)
107
+ if 'detr' in model_name:
108
+
109
+ model = DetrForObjectDetection.from_pretrained(model_name)
110
+
111
+ elif 'yolos' in model_name:
112
+
113
+ model = YolosForObjectDetection.from_pretrained(model_name)
114
+
115
+ tb_label = ""
116
+ if validators.url(url_input):
117
+ image = Image.open(requests.get(url_input, stream=True).raw)
118
+ tb_label = "Confidence Values URL"
119
+
120
+ elif image_input:
121
+ image = image_input
122
+ tb_label = "Confidence Values Upload"
123
+
124
+ #Make prediction
125
+ processed_output_list = make_prediction(image, feature_extractor, model)
126
+ # print("After make_prediction" + str(processed_output_list))
127
+ processed_outputs = processed_output_list[0]
128
+
129
+ #Visualize prediction
130
+ viz_img = visualize_prediction(image, processed_outputs, threshold, model.config.id2label)
131
+
132
+ # return [viz_img, processed_outputs]
133
+ # print(type(viz_img))
134
+
135
+ final_str_abv = ""
136
+ final_str_else = ""
137
+ for score, label, box in sorted(zip(processed_outputs["scores"], processed_outputs["labels"], processed_outputs["boxes"]), key = lambda x: x[0].item(), reverse=True):
138
+ box = [round(i, 2) for i in box.tolist()]
139
+ if score.item() >= threshold:
140
+ final_str_abv += f"Detected `{model.config.id2label[label.item()]}` with confidence `{round(score.item(), 3)}` at location `{box}`\n"
141
+ else:
142
+ final_str_else += f"Detected `{model.config.id2label[label.item()]}` with confidence `{round(score.item(), 3)}` at location `{box}`\n"
143
+
144
+ # https://docs.python.org/3/library/string.html#format-examples
145
+ final_str = "{:*^50}\n".format("ABOVE THRESHOLD OR EQUAL") + final_str_abv + "\n{:*^50}\n".format("BELOW THRESHOLD")+final_str_else
146
+
147
+ return viz_img, final_str
148
+
149
+
150
+ title = """<h1 id="title">Object Detection App with DETR and YOLOS</h1>"""
151
+
152
+ description = """
153
+ Links to HuggingFace Models:
154
+
155
+ - [facebook/detr-resnet-50](https://huggingface.co/facebook/detr-resnet-50)
156
+ - [facebook/detr-resnet-101](https://huggingface.co/facebook/detr-resnet-101)
157
+ - [hustvl/yolos-small](https://huggingface.co/hustvl/yolos-small)
158
+ - [hustvl/yolos-tiny](https://huggingface.co/hustvl/yolos-tiny)
159
+ - [facebook/detr-resnet-101-dc5](https://huggingface.co/facebook/detr-resnet-101-dc5)
160
+ - [hustvl/yolos-small-300](https://huggingface.co/hustvl/yolos-small-300)
161
+ - [mshamrai/yolov8x-visdrone](https://huggingface.co/mshamrai/yolov8x-visdrone)
162
+
163
+ """
164
+
165
+ models = ["facebook/detr-resnet-50","facebook/detr-resnet-101",'hustvl/yolos-small','hustvl/yolos-tiny','facebook/detr-resnet-101-dc5', 'hustvl/yolos-small-300', 'mshamrai/yolov8x-visdrone']
166
+ urls = ["https://c8.alamy.com/comp/J2AB4K/the-new-york-stock-exchange-on-the-wall-street-in-new-york-J2AB4K.jpg"]
167
+
168
+
169
+ TEST_IMAGE = Image.open(r"images/Test_Street_VisDrone.JPG")
170
+
171
+ # image_functions.detect_objects('facebook/detr-resnet-50', "", image_functions.TEST_IMAGE, 0.7)