kevinconka commited on
Commit
e921d65
·
1 Parent(s): 244777e

1st working version

Browse files
Files changed (4) hide show
  1. .gitignore +168 -0
  2. app.py +99 -0
  3. requirements.txt +2 -0
  4. utils.py +39 -0
.gitignore ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # gradio
2
+ flagged*/
3
+ gradio_cached_examples/
4
+ *ipynb
5
+
6
+ # macOS
7
+ .DS_Store
8
+
9
+ # Byte-compiled / optimized / DLL files
10
+ __pycache__/
11
+ *.py[cod]
12
+ *$py.class
13
+
14
+ # C extensions
15
+ *.so
16
+
17
+ # Distribution / packaging
18
+ .Python
19
+ build/
20
+ develop-eggs/
21
+ dist/
22
+ downloads/
23
+ eggs/
24
+ .eggs/
25
+ lib/
26
+ lib64/
27
+ parts/
28
+ sdist/
29
+ var/
30
+ wheels/
31
+ share/python-wheels/
32
+ *.egg-info/
33
+ .installed.cfg
34
+ *.egg
35
+ MANIFEST
36
+
37
+ # PyInstaller
38
+ # Usually these files are written by a python script from a template
39
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
40
+ *.manifest
41
+ *.spec
42
+
43
+ # Installer logs
44
+ pip-log.txt
45
+ pip-delete-this-directory.txt
46
+
47
+ # Unit test / coverage reports
48
+ htmlcov/
49
+ .tox/
50
+ .nox/
51
+ .coverage
52
+ .coverage.*
53
+ .cache
54
+ nosetests.xml
55
+ coverage.xml
56
+ *.cover
57
+ *.py,cover
58
+ .hypothesis/
59
+ .pytest_cache/
60
+ cover/
61
+
62
+ # Translations
63
+ *.mo
64
+ *.pot
65
+
66
+ # Django stuff:
67
+ *.log
68
+ local_settings.py
69
+ db.sqlite3
70
+ db.sqlite3-journal
71
+
72
+ # Flask stuff:
73
+ instance/
74
+ .webassets-cache
75
+
76
+ # Scrapy stuff:
77
+ .scrapy
78
+
79
+ # Sphinx documentation
80
+ docs/_build/
81
+
82
+ # PyBuilder
83
+ .pybuilder/
84
+ target/
85
+
86
+ # Jupyter Notebook
87
+ .ipynb_checkpoints
88
+
89
+ # IPython
90
+ profile_default/
91
+ ipython_config.py
92
+
93
+ # pyenv
94
+ # For a library or package, you might want to ignore these files since the code is
95
+ # intended to run in multiple environments; otherwise, check them in:
96
+ # .python-version
97
+
98
+ # pipenv
99
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
100
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
101
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
102
+ # install all needed dependencies.
103
+ #Pipfile.lock
104
+
105
+ # poetry
106
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
107
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
108
+ # commonly ignored for libraries.
109
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
110
+ #poetry.lock
111
+
112
+ # pdm
113
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
114
+ #pdm.lock
115
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
116
+ # in version control.
117
+ # https://pdm.fming.dev/#use-with-ide
118
+ .pdm.toml
119
+
120
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
121
+ __pypackages__/
122
+
123
+ # Celery stuff
124
+ celerybeat-schedule
125
+ celerybeat.pid
126
+
127
+ # SageMath parsed files
128
+ *.sage.py
129
+
130
+ # Environments
131
+ .env
132
+ .venv
133
+ env/
134
+ venv/
135
+ ENV/
136
+ env.bak/
137
+ venv.bak/
138
+
139
+ # Spyder project settings
140
+ .spyderproject
141
+ .spyproject
142
+
143
+ # Rope project settings
144
+ .ropeproject
145
+
146
+ # mkdocs documentation
147
+ /site
148
+
149
+ # mypy
150
+ .mypy_cache/
151
+ .dmypy.json
152
+ dmypy.json
153
+
154
+ # Pyre type checker
155
+ .pyre/
156
+
157
+ # pytype static type analyzer
158
+ .pytype/
159
+
160
+ # Cython debug symbols
161
+ cython_debug/
162
+
163
+ # PyCharm
164
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
165
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
166
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
167
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
168
+ #.idea/
app.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from utils import load_model, load_image_from_url, inference
3
+
4
+
5
+ TITLE = """
6
+ <p align="right">
7
+ <img alt="Static Badge" src="https://img.shields.io/badge/SEA.AI-beta-blue">
8
+ </p>
9
+ <div align="center">
10
+ <h1>RGB Detection Demo</h1>
11
+ Give it a try! Upload an image or enter a URL to an image and click submit.
12
+ </div>
13
+ """
14
+
15
+ NOTICE = """
16
+ Don't like what you see? Help us improve the model by flagging
17
+ incorrect predictions. Click on `Flag` to submit the image to
18
+ us for review and we'll use it to improve the A.I.
19
+ """
20
+
21
+
22
+ model = load_model("SEA-AI/yolov5n6-RGB", img_size=1280)
23
+ model.conf = 0.25
24
+ model.iou = 0.4
25
+ model.max_det = 100
26
+ model.agnostic = True # NMS class-agnostic
27
+
28
+ # This callback will be used to flag images
29
+ callback = gr.CSVLogger()
30
+
31
+ css = """
32
+ h1 {
33
+ text-align: center;
34
+ display: block;
35
+ }
36
+ """
37
+
38
+ with gr.Blocks(css=css) as demo:
39
+ gr.Markdown(value=TITLE)
40
+
41
+ with gr.Row():
42
+ with gr.Column():
43
+ img_input = gr.Image(label="input", interactive=True)
44
+ img_url = gr.Textbox(
45
+ lines=1,
46
+ placeholder="or enter URL to image here",
47
+ label="input_url",
48
+ show_label=False,
49
+ )
50
+ with gr.Row():
51
+ clear = gr.ClearButton()
52
+ submit = gr.Button("Submit", variant="primary")
53
+ with gr.Column():
54
+ img_output = gr.Image(
55
+ label="output", interactive=False, show_share_button=True
56
+ )
57
+ flag = gr.Button("Flag", visible=False)
58
+ notice = gr.Markdown(value=NOTICE, visible=False)
59
+
60
+ gr.Examples(
61
+ examples=[
62
+ "https://images.pexels.com/photos/273886/pexels-photo-273886.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
63
+ "https://images.pexels.com/photos/913111/pexels-photo-913111.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
64
+ "https://images.pexels.com/photos/88517/pexels-photo-88517.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
65
+ ],
66
+ inputs=img_input,
67
+ outputs=img_output,
68
+ fn=lambda image: inference(model, image),
69
+ cache_examples=True,
70
+ )
71
+
72
+ # add components to clear
73
+ clear.add([img_input, img_url, img_output])
74
+
75
+ # event listeners
76
+ img_url.change(load_image_from_url, [img_url], img_input)
77
+ submit.click(lambda *args: inference(model, args), [img_input], img_output)
78
+
79
+ @img_output.change(inputs=[img_output], outputs=[flag, notice])
80
+ def show_hide(img_output):
81
+ visible = img_output is not None
82
+ return {
83
+ flag: gr.Button("Flag", visible=visible),
84
+ notice: gr.Markdown(value=NOTICE, visible=visible),
85
+ }
86
+
87
+ # This needs to be called prior to the first call to callback.flag()
88
+ callback.setup([img_input, img_url, img_output], "flagged")
89
+
90
+ # We can choose which components to flag (in this case, we'll flag all)
91
+ flag.click(
92
+ lambda *args: callback.flag(args),
93
+ [img_input, img_url, img_output],
94
+ None,
95
+ preprocess=False,
96
+ ).then(lambda: gr.Info("Thank you for contributing!"))
97
+
98
+
99
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ yolov5
2
+ pillow
utils.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ from io import BytesIO
4
+ import numpy as np
5
+ from PIL import Image
6
+ import yolov5
7
+ from yolov5.utils.plots import Annotator, colors
8
+ import gradio as gr
9
+
10
+
11
+ def load_model(model_path, img_size=640):
12
+ HF_TOKEN = os.getenv("HF_TOKEN")
13
+ if HF_TOKEN is not None: # assume SECRET variable is set
14
+ model = yolov5.load(model_path, hf_token=HF_TOKEN)
15
+ else:
16
+ model = yolov5.load(model_path)
17
+ model.img_size = img_size # add img_size attribute
18
+ return model
19
+
20
+
21
+ def load_image_from_url(url):
22
+ if not url: # empty or None
23
+ return gr.Image(interactive=True)
24
+ try:
25
+ response = requests.get(url, timeout=5)
26
+ image = Image.open(BytesIO(response.content))
27
+ except Exception as e:
28
+ raise gr.Error("Unable to load image from URL") from e
29
+ return image.convert("RGB")
30
+
31
+
32
+ def inference(model, image):
33
+ results = model(image, size=model.img_size)
34
+ annotator = Annotator(np.asarray(image))
35
+ for *box, _, cls in reversed(results.pred[0]):
36
+ # label = f'{model.names[int(cls)]} {conf:.2f}'
37
+ # print(f'{cls} {conf:.2f} {box}')
38
+ annotator.box_label(box, "", color=colors(cls, True))
39
+ return annotator.im