ultralytics 8.1.29__py3-none-any.whl → 8.3.63__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tests/__init__.py +22 -0
- tests/conftest.py +83 -0
- tests/test_cli.py +122 -0
- tests/test_cuda.py +155 -0
- tests/test_engine.py +131 -0
- tests/test_exports.py +216 -0
- tests/test_integrations.py +150 -0
- tests/test_python.py +615 -0
- tests/test_solutions.py +94 -0
- ultralytics/__init__.py +11 -8
- ultralytics/cfg/__init__.py +569 -131
- ultralytics/cfg/datasets/Argoverse.yaml +2 -1
- ultralytics/cfg/datasets/DOTAv1.5.yaml +3 -2
- ultralytics/cfg/datasets/DOTAv1.yaml +3 -2
- ultralytics/cfg/datasets/GlobalWheat2020.yaml +3 -2
- ultralytics/cfg/datasets/ImageNet.yaml +2 -1
- ultralytics/cfg/datasets/Objects365.yaml +5 -4
- ultralytics/cfg/datasets/SKU-110K.yaml +2 -1
- ultralytics/cfg/datasets/VOC.yaml +3 -2
- ultralytics/cfg/datasets/VisDrone.yaml +6 -5
- ultralytics/cfg/datasets/african-wildlife.yaml +25 -0
- ultralytics/cfg/datasets/brain-tumor.yaml +23 -0
- ultralytics/cfg/datasets/carparts-seg.yaml +3 -2
- ultralytics/cfg/datasets/coco-pose.yaml +7 -6
- ultralytics/cfg/datasets/coco.yaml +3 -2
- ultralytics/cfg/datasets/coco128-seg.yaml +4 -3
- ultralytics/cfg/datasets/coco128.yaml +4 -3
- ultralytics/cfg/datasets/coco8-pose.yaml +3 -2
- ultralytics/cfg/datasets/coco8-seg.yaml +3 -2
- ultralytics/cfg/datasets/coco8.yaml +3 -2
- ultralytics/cfg/datasets/crack-seg.yaml +3 -2
- ultralytics/cfg/datasets/dog-pose.yaml +24 -0
- ultralytics/cfg/datasets/dota8.yaml +3 -2
- ultralytics/cfg/datasets/hand-keypoints.yaml +26 -0
- ultralytics/cfg/datasets/lvis.yaml +1236 -0
- ultralytics/cfg/datasets/medical-pills.yaml +22 -0
- ultralytics/cfg/datasets/open-images-v7.yaml +2 -1
- ultralytics/cfg/datasets/package-seg.yaml +5 -4
- ultralytics/cfg/datasets/signature.yaml +21 -0
- ultralytics/cfg/datasets/tiger-pose.yaml +3 -2
- ultralytics/cfg/datasets/xView.yaml +2 -1
- ultralytics/cfg/default.yaml +14 -11
- ultralytics/cfg/models/11/yolo11-cls-resnet18.yaml +24 -0
- ultralytics/cfg/models/11/yolo11-cls.yaml +33 -0
- ultralytics/cfg/models/11/yolo11-obb.yaml +50 -0
- ultralytics/cfg/models/11/yolo11-pose.yaml +51 -0
- ultralytics/cfg/models/11/yolo11-seg.yaml +50 -0
- ultralytics/cfg/models/11/yolo11.yaml +50 -0
- ultralytics/cfg/models/rt-detr/rtdetr-l.yaml +5 -2
- ultralytics/cfg/models/rt-detr/rtdetr-resnet101.yaml +5 -2
- ultralytics/cfg/models/rt-detr/rtdetr-resnet50.yaml +5 -2
- ultralytics/cfg/models/rt-detr/rtdetr-x.yaml +5 -2
- ultralytics/cfg/models/v10/yolov10b.yaml +45 -0
- ultralytics/cfg/models/v10/yolov10l.yaml +45 -0
- ultralytics/cfg/models/v10/yolov10m.yaml +45 -0
- ultralytics/cfg/models/v10/yolov10n.yaml +45 -0
- ultralytics/cfg/models/v10/yolov10s.yaml +45 -0
- ultralytics/cfg/models/v10/yolov10x.yaml +45 -0
- ultralytics/cfg/models/v3/yolov3-spp.yaml +5 -2
- ultralytics/cfg/models/v3/yolov3-tiny.yaml +5 -2
- ultralytics/cfg/models/v3/yolov3.yaml +5 -2
- ultralytics/cfg/models/v5/yolov5-p6.yaml +5 -2
- ultralytics/cfg/models/v5/yolov5.yaml +5 -2
- ultralytics/cfg/models/v6/yolov6.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-cls-resnet101.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-cls-resnet50.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-cls.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-ghost-p2.yaml +6 -2
- ultralytics/cfg/models/v8/yolov8-ghost-p6.yaml +6 -2
- ultralytics/cfg/models/v8/yolov8-ghost.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-obb.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-p2.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-p6.yaml +10 -7
- ultralytics/cfg/models/v8/yolov8-pose-p6.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-pose.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-rtdetr.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-seg-p6.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-seg.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-world.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8-worldv2.yaml +5 -2
- ultralytics/cfg/models/v8/yolov8.yaml +5 -2
- ultralytics/cfg/models/v9/yolov9c-seg.yaml +41 -0
- ultralytics/cfg/models/v9/yolov9c.yaml +30 -25
- ultralytics/cfg/models/v9/yolov9e-seg.yaml +64 -0
- ultralytics/cfg/models/v9/yolov9e.yaml +46 -42
- ultralytics/cfg/models/v9/yolov9m.yaml +41 -0
- ultralytics/cfg/models/v9/yolov9s.yaml +41 -0
- ultralytics/cfg/models/v9/yolov9t.yaml +41 -0
- ultralytics/cfg/solutions/default.yaml +24 -0
- ultralytics/cfg/trackers/botsort.yaml +8 -5
- ultralytics/cfg/trackers/bytetrack.yaml +8 -5
- ultralytics/data/__init__.py +14 -3
- ultralytics/data/annotator.py +37 -15
- ultralytics/data/augment.py +1783 -289
- ultralytics/data/base.py +62 -27
- ultralytics/data/build.py +37 -8
- ultralytics/data/converter.py +196 -36
- ultralytics/data/dataset.py +233 -94
- ultralytics/data/loaders.py +199 -96
- ultralytics/data/split_dota.py +39 -29
- ultralytics/data/utils.py +111 -41
- ultralytics/engine/__init__.py +1 -1
- ultralytics/engine/exporter.py +579 -244
- ultralytics/engine/model.py +604 -252
- ultralytics/engine/predictor.py +22 -11
- ultralytics/engine/results.py +1228 -218
- ultralytics/engine/trainer.py +191 -129
- ultralytics/engine/tuner.py +18 -18
- ultralytics/engine/validator.py +18 -15
- ultralytics/hub/__init__.py +31 -13
- ultralytics/hub/auth.py +11 -7
- ultralytics/hub/google/__init__.py +159 -0
- ultralytics/hub/session.py +128 -94
- ultralytics/hub/utils.py +20 -21
- ultralytics/models/__init__.py +4 -2
- ultralytics/models/fastsam/__init__.py +2 -3
- ultralytics/models/fastsam/model.py +26 -4
- ultralytics/models/fastsam/predict.py +127 -63
- ultralytics/models/fastsam/utils.py +1 -44
- ultralytics/models/fastsam/val.py +1 -1
- ultralytics/models/nas/__init__.py +1 -1
- ultralytics/models/nas/model.py +21 -10
- ultralytics/models/nas/predict.py +3 -6
- ultralytics/models/nas/val.py +4 -4
- ultralytics/models/rtdetr/__init__.py +1 -1
- ultralytics/models/rtdetr/model.py +1 -1
- ultralytics/models/rtdetr/predict.py +6 -8
- ultralytics/models/rtdetr/train.py +6 -2
- ultralytics/models/rtdetr/val.py +3 -3
- ultralytics/models/sam/__init__.py +3 -3
- ultralytics/models/sam/amg.py +29 -23
- ultralytics/models/sam/build.py +211 -13
- ultralytics/models/sam/model.py +91 -30
- ultralytics/models/sam/modules/__init__.py +1 -1
- ultralytics/models/sam/modules/blocks.py +1129 -0
- ultralytics/models/sam/modules/decoders.py +381 -53
- ultralytics/models/sam/modules/encoders.py +515 -324
- ultralytics/models/sam/modules/memory_attention.py +237 -0
- ultralytics/models/sam/modules/sam.py +969 -21
- ultralytics/models/sam/modules/tiny_encoder.py +425 -154
- ultralytics/models/sam/modules/transformer.py +159 -60
- ultralytics/models/sam/modules/utils.py +293 -0
- ultralytics/models/sam/predict.py +1263 -132
- ultralytics/models/utils/__init__.py +1 -1
- ultralytics/models/utils/loss.py +36 -24
- ultralytics/models/utils/ops.py +3 -7
- ultralytics/models/yolo/__init__.py +3 -3
- ultralytics/models/yolo/classify/__init__.py +1 -1
- ultralytics/models/yolo/classify/predict.py +7 -8
- ultralytics/models/yolo/classify/train.py +17 -22
- ultralytics/models/yolo/classify/val.py +8 -4
- ultralytics/models/yolo/detect/__init__.py +1 -1
- ultralytics/models/yolo/detect/predict.py +3 -5
- ultralytics/models/yolo/detect/train.py +11 -4
- ultralytics/models/yolo/detect/val.py +90 -52
- ultralytics/models/yolo/model.py +14 -9
- ultralytics/models/yolo/obb/__init__.py +1 -1
- ultralytics/models/yolo/obb/predict.py +2 -2
- ultralytics/models/yolo/obb/train.py +5 -3
- ultralytics/models/yolo/obb/val.py +41 -23
- ultralytics/models/yolo/pose/__init__.py +1 -1
- ultralytics/models/yolo/pose/predict.py +3 -5
- ultralytics/models/yolo/pose/train.py +2 -2
- ultralytics/models/yolo/pose/val.py +51 -17
- ultralytics/models/yolo/segment/__init__.py +1 -1
- ultralytics/models/yolo/segment/predict.py +3 -5
- ultralytics/models/yolo/segment/train.py +2 -2
- ultralytics/models/yolo/segment/val.py +60 -19
- ultralytics/models/yolo/world/__init__.py +5 -0
- ultralytics/models/yolo/world/train.py +92 -0
- ultralytics/models/yolo/world/train_world.py +109 -0
- ultralytics/nn/__init__.py +1 -1
- ultralytics/nn/autobackend.py +228 -93
- ultralytics/nn/modules/__init__.py +39 -14
- ultralytics/nn/modules/activation.py +21 -0
- ultralytics/nn/modules/block.py +526 -66
- ultralytics/nn/modules/conv.py +24 -7
- ultralytics/nn/modules/head.py +177 -34
- ultralytics/nn/modules/transformer.py +6 -5
- ultralytics/nn/modules/utils.py +1 -2
- ultralytics/nn/tasks.py +226 -82
- ultralytics/solutions/__init__.py +30 -1
- ultralytics/solutions/ai_gym.py +96 -143
- ultralytics/solutions/analytics.py +247 -0
- ultralytics/solutions/distance_calculation.py +78 -135
- ultralytics/solutions/heatmap.py +93 -247
- ultralytics/solutions/object_counter.py +184 -259
- ultralytics/solutions/parking_management.py +246 -0
- ultralytics/solutions/queue_management.py +112 -0
- ultralytics/solutions/region_counter.py +116 -0
- ultralytics/solutions/security_alarm.py +144 -0
- ultralytics/solutions/solutions.py +178 -0
- ultralytics/solutions/speed_estimation.py +86 -174
- ultralytics/solutions/streamlit_inference.py +190 -0
- ultralytics/solutions/trackzone.py +68 -0
- ultralytics/trackers/__init__.py +1 -1
- ultralytics/trackers/basetrack.py +32 -13
- ultralytics/trackers/bot_sort.py +61 -28
- ultralytics/trackers/byte_tracker.py +83 -51
- ultralytics/trackers/track.py +21 -6
- ultralytics/trackers/utils/__init__.py +1 -1
- ultralytics/trackers/utils/gmc.py +62 -48
- ultralytics/trackers/utils/kalman_filter.py +166 -35
- ultralytics/trackers/utils/matching.py +40 -21
- ultralytics/utils/__init__.py +511 -239
- ultralytics/utils/autobatch.py +40 -22
- ultralytics/utils/benchmarks.py +266 -85
- ultralytics/utils/callbacks/__init__.py +1 -1
- ultralytics/utils/callbacks/base.py +1 -3
- ultralytics/utils/callbacks/clearml.py +7 -6
- ultralytics/utils/callbacks/comet.py +39 -17
- ultralytics/utils/callbacks/dvc.py +1 -1
- ultralytics/utils/callbacks/hub.py +16 -16
- ultralytics/utils/callbacks/mlflow.py +28 -24
- ultralytics/utils/callbacks/neptune.py +6 -2
- ultralytics/utils/callbacks/raytune.py +3 -4
- ultralytics/utils/callbacks/tensorboard.py +18 -18
- ultralytics/utils/callbacks/wb.py +27 -20
- ultralytics/utils/checks.py +172 -100
- ultralytics/utils/dist.py +2 -1
- ultralytics/utils/downloads.py +40 -34
- ultralytics/utils/errors.py +1 -1
- ultralytics/utils/files.py +72 -38
- ultralytics/utils/instance.py +41 -19
- ultralytics/utils/loss.py +83 -55
- ultralytics/utils/metrics.py +61 -56
- ultralytics/utils/ops.py +94 -89
- ultralytics/utils/patches.py +30 -14
- ultralytics/utils/plotting.py +600 -269
- ultralytics/utils/tal.py +67 -26
- ultralytics/utils/torch_utils.py +305 -112
- ultralytics/utils/triton.py +2 -1
- ultralytics/utils/tuner.py +21 -12
- ultralytics-8.3.63.dist-info/METADATA +370 -0
- ultralytics-8.3.63.dist-info/RECORD +241 -0
- {ultralytics-8.1.29.dist-info → ultralytics-8.3.63.dist-info}/WHEEL +1 -1
- ultralytics/data/explorer/__init__.py +0 -5
- ultralytics/data/explorer/explorer.py +0 -472
- ultralytics/data/explorer/gui/__init__.py +0 -1
- ultralytics/data/explorer/gui/dash.py +0 -268
- ultralytics/data/explorer/utils.py +0 -166
- ultralytics/models/fastsam/prompt.py +0 -357
- ultralytics-8.1.29.dist-info/METADATA +0 -373
- ultralytics-8.1.29.dist-info/RECORD +0 -197
- {ultralytics-8.1.29.dist-info → ultralytics-8.3.63.dist-info}/LICENSE +0 -0
- {ultralytics-8.1.29.dist-info → ultralytics-8.3.63.dist-info}/entry_points.txt +0 -0
- {ultralytics-8.1.29.dist-info → ultralytics-8.3.63.dist-info}/top_level.txt +0 -0
@@ -1,268 +0,0 @@
|
|
1
|
-
# Ultralytics YOLO 🚀, AGPL-3.0 license
|
2
|
-
|
3
|
-
import time
|
4
|
-
from threading import Thread
|
5
|
-
|
6
|
-
import pandas as pd
|
7
|
-
|
8
|
-
from ultralytics import Explorer
|
9
|
-
from ultralytics.utils import ROOT, SETTINGS
|
10
|
-
from ultralytics.utils.checks import check_requirements
|
11
|
-
|
12
|
-
check_requirements(("streamlit>=1.29.0", "streamlit-select>=0.3"))
|
13
|
-
|
14
|
-
import streamlit as st
|
15
|
-
from streamlit_select import image_select
|
16
|
-
|
17
|
-
|
18
|
-
def _get_explorer():
|
19
|
-
"""Initializes and returns an instance of the Explorer class."""
|
20
|
-
exp = Explorer(data=st.session_state.get("dataset"), model=st.session_state.get("model"))
|
21
|
-
thread = Thread(
|
22
|
-
target=exp.create_embeddings_table, kwargs={"force": st.session_state.get("force_recreate_embeddings")}
|
23
|
-
)
|
24
|
-
thread.start()
|
25
|
-
progress_bar = st.progress(0, text="Creating embeddings table...")
|
26
|
-
while exp.progress < 1:
|
27
|
-
time.sleep(0.1)
|
28
|
-
progress_bar.progress(exp.progress, text=f"Progress: {exp.progress * 100}%")
|
29
|
-
thread.join()
|
30
|
-
st.session_state["explorer"] = exp
|
31
|
-
progress_bar.empty()
|
32
|
-
|
33
|
-
|
34
|
-
def init_explorer_form():
|
35
|
-
"""Initializes an Explorer instance and creates embeddings table with progress tracking."""
|
36
|
-
datasets = ROOT / "cfg" / "datasets"
|
37
|
-
ds = [d.name for d in datasets.glob("*.yaml")]
|
38
|
-
models = [
|
39
|
-
"yolov8n.pt",
|
40
|
-
"yolov8s.pt",
|
41
|
-
"yolov8m.pt",
|
42
|
-
"yolov8l.pt",
|
43
|
-
"yolov8x.pt",
|
44
|
-
"yolov8n-seg.pt",
|
45
|
-
"yolov8s-seg.pt",
|
46
|
-
"yolov8m-seg.pt",
|
47
|
-
"yolov8l-seg.pt",
|
48
|
-
"yolov8x-seg.pt",
|
49
|
-
"yolov8n-pose.pt",
|
50
|
-
"yolov8s-pose.pt",
|
51
|
-
"yolov8m-pose.pt",
|
52
|
-
"yolov8l-pose.pt",
|
53
|
-
"yolov8x-pose.pt",
|
54
|
-
]
|
55
|
-
with st.form(key="explorer_init_form"):
|
56
|
-
col1, col2 = st.columns(2)
|
57
|
-
with col1:
|
58
|
-
st.selectbox("Select dataset", ds, key="dataset", index=ds.index("coco128.yaml"))
|
59
|
-
with col2:
|
60
|
-
st.selectbox("Select model", models, key="model")
|
61
|
-
st.checkbox("Force recreate embeddings", key="force_recreate_embeddings")
|
62
|
-
|
63
|
-
st.form_submit_button("Explore", on_click=_get_explorer)
|
64
|
-
|
65
|
-
|
66
|
-
def query_form():
|
67
|
-
"""Sets up a form in Streamlit to initialize Explorer with dataset and model selection."""
|
68
|
-
with st.form("query_form"):
|
69
|
-
col1, col2 = st.columns([0.8, 0.2])
|
70
|
-
with col1:
|
71
|
-
st.text_input(
|
72
|
-
"Query",
|
73
|
-
"WHERE labels LIKE '%person%' AND labels LIKE '%dog%'",
|
74
|
-
label_visibility="collapsed",
|
75
|
-
key="query",
|
76
|
-
)
|
77
|
-
with col2:
|
78
|
-
st.form_submit_button("Query", on_click=run_sql_query)
|
79
|
-
|
80
|
-
|
81
|
-
def ai_query_form():
|
82
|
-
"""Sets up a Streamlit form for user input to initialize Explorer with dataset and model selection."""
|
83
|
-
with st.form("ai_query_form"):
|
84
|
-
col1, col2 = st.columns([0.8, 0.2])
|
85
|
-
with col1:
|
86
|
-
st.text_input("Query", "Show images with 1 person and 1 dog", label_visibility="collapsed", key="ai_query")
|
87
|
-
with col2:
|
88
|
-
st.form_submit_button("Ask AI", on_click=run_ai_query)
|
89
|
-
|
90
|
-
|
91
|
-
def find_similar_imgs(imgs):
|
92
|
-
"""Initializes a Streamlit form for AI-based image querying with custom input."""
|
93
|
-
exp = st.session_state["explorer"]
|
94
|
-
similar = exp.get_similar(img=imgs, limit=st.session_state.get("limit"), return_type="arrow")
|
95
|
-
paths = similar.to_pydict()["im_file"]
|
96
|
-
st.session_state["imgs"] = paths
|
97
|
-
st.session_state["res"] = similar
|
98
|
-
|
99
|
-
|
100
|
-
def similarity_form(selected_imgs):
|
101
|
-
"""Initializes a form for AI-based image querying with custom input in Streamlit."""
|
102
|
-
st.write("Similarity Search")
|
103
|
-
with st.form("similarity_form"):
|
104
|
-
subcol1, subcol2 = st.columns([1, 1])
|
105
|
-
with subcol1:
|
106
|
-
st.number_input(
|
107
|
-
"limit", min_value=None, max_value=None, value=25, label_visibility="collapsed", key="limit"
|
108
|
-
)
|
109
|
-
|
110
|
-
with subcol2:
|
111
|
-
disabled = not len(selected_imgs)
|
112
|
-
st.write("Selected: ", len(selected_imgs))
|
113
|
-
st.form_submit_button(
|
114
|
-
"Search",
|
115
|
-
disabled=disabled,
|
116
|
-
on_click=find_similar_imgs,
|
117
|
-
args=(selected_imgs,),
|
118
|
-
)
|
119
|
-
if disabled:
|
120
|
-
st.error("Select at least one image to search.")
|
121
|
-
|
122
|
-
|
123
|
-
# def persist_reset_form():
|
124
|
-
# with st.form("persist_reset"):
|
125
|
-
# col1, col2 = st.columns([1, 1])
|
126
|
-
# with col1:
|
127
|
-
# st.form_submit_button("Reset", on_click=reset)
|
128
|
-
#
|
129
|
-
# with col2:
|
130
|
-
# st.form_submit_button("Persist", on_click=update_state, args=("PERSISTING", True))
|
131
|
-
|
132
|
-
|
133
|
-
def run_sql_query():
|
134
|
-
"""Executes an SQL query and returns the results."""
|
135
|
-
st.session_state["error"] = None
|
136
|
-
query = st.session_state.get("query")
|
137
|
-
if query.rstrip().lstrip():
|
138
|
-
exp = st.session_state["explorer"]
|
139
|
-
res = exp.sql_query(query, return_type="arrow")
|
140
|
-
st.session_state["imgs"] = res.to_pydict()["im_file"]
|
141
|
-
st.session_state["res"] = res
|
142
|
-
|
143
|
-
|
144
|
-
def run_ai_query():
|
145
|
-
"""Execute SQL query and update session state with query results."""
|
146
|
-
if not SETTINGS["openai_api_key"]:
|
147
|
-
st.session_state["error"] = (
|
148
|
-
'OpenAI API key not found in settings. Please run yolo settings openai_api_key="..."'
|
149
|
-
)
|
150
|
-
return
|
151
|
-
st.session_state["error"] = None
|
152
|
-
query = st.session_state.get("ai_query")
|
153
|
-
if query.rstrip().lstrip():
|
154
|
-
exp = st.session_state["explorer"]
|
155
|
-
res = exp.ask_ai(query)
|
156
|
-
if not isinstance(res, pd.DataFrame) or res.empty:
|
157
|
-
st.session_state["error"] = "No results found using AI generated query. Try another query or rerun it."
|
158
|
-
return
|
159
|
-
st.session_state["imgs"] = res["im_file"].to_list()
|
160
|
-
st.session_state["res"] = res
|
161
|
-
|
162
|
-
|
163
|
-
def reset_explorer():
|
164
|
-
"""Resets the explorer to its initial state by clearing session variables."""
|
165
|
-
st.session_state["explorer"] = None
|
166
|
-
st.session_state["imgs"] = None
|
167
|
-
st.session_state["error"] = None
|
168
|
-
|
169
|
-
|
170
|
-
def utralytics_explorer_docs_callback():
|
171
|
-
"""Resets the explorer to its initial state by clearing session variables."""
|
172
|
-
with st.container(border=True):
|
173
|
-
st.image(
|
174
|
-
"https://raw.githubusercontent.com/ultralytics/assets/main/logo/Ultralytics_Logotype_Original.svg",
|
175
|
-
width=100,
|
176
|
-
)
|
177
|
-
st.markdown(
|
178
|
-
"<p>This demo is built using Ultralytics Explorer API. Visit <a href='https://docs.ultralytics.com/datasets/explorer/'>API docs</a> to try examples & learn more</p>",
|
179
|
-
unsafe_allow_html=True,
|
180
|
-
help=None,
|
181
|
-
)
|
182
|
-
st.link_button("Ultrlaytics Explorer API", "https://docs.ultralytics.com/datasets/explorer/")
|
183
|
-
|
184
|
-
|
185
|
-
def layout():
|
186
|
-
"""Resets explorer session variables and provides documentation with a link to API docs."""
|
187
|
-
st.set_page_config(layout="wide", initial_sidebar_state="collapsed")
|
188
|
-
st.markdown("<h1 style='text-align: center;'>Ultralytics Explorer Demo</h1>", unsafe_allow_html=True)
|
189
|
-
|
190
|
-
if st.session_state.get("explorer") is None:
|
191
|
-
init_explorer_form()
|
192
|
-
return
|
193
|
-
|
194
|
-
st.button(":arrow_backward: Select Dataset", on_click=reset_explorer)
|
195
|
-
exp = st.session_state.get("explorer")
|
196
|
-
col1, col2 = st.columns([0.75, 0.25], gap="small")
|
197
|
-
imgs = []
|
198
|
-
if st.session_state.get("error"):
|
199
|
-
st.error(st.session_state["error"])
|
200
|
-
else:
|
201
|
-
if st.session_state.get("imgs"):
|
202
|
-
imgs = st.session_state.get("imgs")
|
203
|
-
else:
|
204
|
-
imgs = exp.table.to_lance().to_table(columns=["im_file"]).to_pydict()["im_file"]
|
205
|
-
st.session_state["res"] = exp.table.to_arrow()
|
206
|
-
total_imgs, selected_imgs = len(imgs), []
|
207
|
-
with col1:
|
208
|
-
subcol1, subcol2, subcol3, subcol4, subcol5 = st.columns(5)
|
209
|
-
with subcol1:
|
210
|
-
st.write("Max Images Displayed:")
|
211
|
-
with subcol2:
|
212
|
-
num = st.number_input(
|
213
|
-
"Max Images Displayed",
|
214
|
-
min_value=0,
|
215
|
-
max_value=total_imgs,
|
216
|
-
value=min(500, total_imgs),
|
217
|
-
key="num_imgs_displayed",
|
218
|
-
label_visibility="collapsed",
|
219
|
-
)
|
220
|
-
with subcol3:
|
221
|
-
st.write("Start Index:")
|
222
|
-
with subcol4:
|
223
|
-
start_idx = st.number_input(
|
224
|
-
"Start Index",
|
225
|
-
min_value=0,
|
226
|
-
max_value=total_imgs,
|
227
|
-
value=0,
|
228
|
-
key="start_index",
|
229
|
-
label_visibility="collapsed",
|
230
|
-
)
|
231
|
-
with subcol5:
|
232
|
-
reset = st.button("Reset", use_container_width=False, key="reset")
|
233
|
-
if reset:
|
234
|
-
st.session_state["imgs"] = None
|
235
|
-
st.experimental_rerun()
|
236
|
-
|
237
|
-
query_form()
|
238
|
-
ai_query_form()
|
239
|
-
if total_imgs:
|
240
|
-
labels, boxes, masks, kpts, classes = None, None, None, None, None
|
241
|
-
task = exp.model.task
|
242
|
-
if st.session_state.get("display_labels"):
|
243
|
-
labels = st.session_state.get("res").to_pydict()["labels"][start_idx : start_idx + num]
|
244
|
-
boxes = st.session_state.get("res").to_pydict()["bboxes"][start_idx : start_idx + num]
|
245
|
-
masks = st.session_state.get("res").to_pydict()["masks"][start_idx : start_idx + num]
|
246
|
-
kpts = st.session_state.get("res").to_pydict()["keypoints"][start_idx : start_idx + num]
|
247
|
-
classes = st.session_state.get("res").to_pydict()["cls"][start_idx : start_idx + num]
|
248
|
-
imgs_displayed = imgs[start_idx : start_idx + num]
|
249
|
-
selected_imgs = image_select(
|
250
|
-
f"Total samples: {total_imgs}",
|
251
|
-
images=imgs_displayed,
|
252
|
-
use_container_width=False,
|
253
|
-
# indices=[i for i in range(num)] if select_all else None,
|
254
|
-
labels=labels,
|
255
|
-
classes=classes,
|
256
|
-
bboxes=boxes,
|
257
|
-
masks=masks if task == "segment" else None,
|
258
|
-
kpts=kpts if task == "pose" else None,
|
259
|
-
)
|
260
|
-
|
261
|
-
with col2:
|
262
|
-
similarity_form(selected_imgs)
|
263
|
-
display_labels = st.checkbox("Labels", value=False, key="display_labels")
|
264
|
-
utralytics_explorer_docs_callback()
|
265
|
-
|
266
|
-
|
267
|
-
if __name__ == "__main__":
|
268
|
-
layout()
|
@@ -1,166 +0,0 @@
|
|
1
|
-
# Ultralytics YOLO 🚀, AGPL-3.0 license
|
2
|
-
|
3
|
-
import getpass
|
4
|
-
from typing import List
|
5
|
-
|
6
|
-
import cv2
|
7
|
-
import numpy as np
|
8
|
-
import pandas as pd
|
9
|
-
|
10
|
-
from ultralytics.data.augment import LetterBox
|
11
|
-
from ultralytics.utils import LOGGER as logger
|
12
|
-
from ultralytics.utils import SETTINGS
|
13
|
-
from ultralytics.utils.checks import check_requirements
|
14
|
-
from ultralytics.utils.ops import xyxy2xywh
|
15
|
-
from ultralytics.utils.plotting import plot_images
|
16
|
-
|
17
|
-
|
18
|
-
def get_table_schema(vector_size):
|
19
|
-
"""Extracts and returns the schema of a database table."""
|
20
|
-
from lancedb.pydantic import LanceModel, Vector
|
21
|
-
|
22
|
-
class Schema(LanceModel):
|
23
|
-
im_file: str
|
24
|
-
labels: List[str]
|
25
|
-
cls: List[int]
|
26
|
-
bboxes: List[List[float]]
|
27
|
-
masks: List[List[List[int]]]
|
28
|
-
keypoints: List[List[List[float]]]
|
29
|
-
vector: Vector(vector_size)
|
30
|
-
|
31
|
-
return Schema
|
32
|
-
|
33
|
-
|
34
|
-
def get_sim_index_schema():
|
35
|
-
"""Returns a LanceModel schema for a database table with specified vector size."""
|
36
|
-
from lancedb.pydantic import LanceModel
|
37
|
-
|
38
|
-
class Schema(LanceModel):
|
39
|
-
idx: int
|
40
|
-
im_file: str
|
41
|
-
count: int
|
42
|
-
sim_im_files: List[str]
|
43
|
-
|
44
|
-
return Schema
|
45
|
-
|
46
|
-
|
47
|
-
def sanitize_batch(batch, dataset_info):
|
48
|
-
"""Sanitizes input batch for inference, ensuring correct format and dimensions."""
|
49
|
-
batch["cls"] = batch["cls"].flatten().int().tolist()
|
50
|
-
box_cls_pair = sorted(zip(batch["bboxes"].tolist(), batch["cls"]), key=lambda x: x[1])
|
51
|
-
batch["bboxes"] = [box for box, _ in box_cls_pair]
|
52
|
-
batch["cls"] = [cls for _, cls in box_cls_pair]
|
53
|
-
batch["labels"] = [dataset_info["names"][i] for i in batch["cls"]]
|
54
|
-
batch["masks"] = batch["masks"].tolist() if "masks" in batch else [[[]]]
|
55
|
-
batch["keypoints"] = batch["keypoints"].tolist() if "keypoints" in batch else [[[]]]
|
56
|
-
return batch
|
57
|
-
|
58
|
-
|
59
|
-
def plot_query_result(similar_set, plot_labels=True):
|
60
|
-
"""
|
61
|
-
Plot images from the similar set.
|
62
|
-
|
63
|
-
Args:
|
64
|
-
similar_set (list): Pyarrow or pandas object containing the similar data points
|
65
|
-
plot_labels (bool): Whether to plot labels or not
|
66
|
-
"""
|
67
|
-
similar_set = (
|
68
|
-
similar_set.to_dict(orient="list") if isinstance(similar_set, pd.DataFrame) else similar_set.to_pydict()
|
69
|
-
)
|
70
|
-
empty_masks = [[[]]]
|
71
|
-
empty_boxes = [[]]
|
72
|
-
images = similar_set.get("im_file", [])
|
73
|
-
bboxes = similar_set.get("bboxes", []) if similar_set.get("bboxes") is not empty_boxes else []
|
74
|
-
masks = similar_set.get("masks") if similar_set.get("masks")[0] != empty_masks else []
|
75
|
-
kpts = similar_set.get("keypoints") if similar_set.get("keypoints")[0] != empty_masks else []
|
76
|
-
cls = similar_set.get("cls", [])
|
77
|
-
|
78
|
-
plot_size = 640
|
79
|
-
imgs, batch_idx, plot_boxes, plot_masks, plot_kpts = [], [], [], [], []
|
80
|
-
for i, imf in enumerate(images):
|
81
|
-
im = cv2.imread(imf)
|
82
|
-
im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
|
83
|
-
h, w = im.shape[:2]
|
84
|
-
r = min(plot_size / h, plot_size / w)
|
85
|
-
imgs.append(LetterBox(plot_size, center=False)(image=im).transpose(2, 0, 1))
|
86
|
-
if plot_labels:
|
87
|
-
if len(bboxes) > i and len(bboxes[i]) > 0:
|
88
|
-
box = np.array(bboxes[i], dtype=np.float32)
|
89
|
-
box[:, [0, 2]] *= r
|
90
|
-
box[:, [1, 3]] *= r
|
91
|
-
plot_boxes.append(box)
|
92
|
-
if len(masks) > i and len(masks[i]) > 0:
|
93
|
-
mask = np.array(masks[i], dtype=np.uint8)[0]
|
94
|
-
plot_masks.append(LetterBox(plot_size, center=False)(image=mask))
|
95
|
-
if len(kpts) > i and kpts[i] is not None:
|
96
|
-
kpt = np.array(kpts[i], dtype=np.float32)
|
97
|
-
kpt[:, :, :2] *= r
|
98
|
-
plot_kpts.append(kpt)
|
99
|
-
batch_idx.append(np.ones(len(np.array(bboxes[i], dtype=np.float32))) * i)
|
100
|
-
imgs = np.stack(imgs, axis=0)
|
101
|
-
masks = np.stack(plot_masks, axis=0) if plot_masks else np.zeros(0, dtype=np.uint8)
|
102
|
-
kpts = np.concatenate(plot_kpts, axis=0) if plot_kpts else np.zeros((0, 51), dtype=np.float32)
|
103
|
-
boxes = xyxy2xywh(np.concatenate(plot_boxes, axis=0)) if plot_boxes else np.zeros(0, dtype=np.float32)
|
104
|
-
batch_idx = np.concatenate(batch_idx, axis=0)
|
105
|
-
cls = np.concatenate([np.array(c, dtype=np.int32) for c in cls], axis=0)
|
106
|
-
|
107
|
-
return plot_images(
|
108
|
-
imgs, batch_idx, cls, bboxes=boxes, masks=masks, kpts=kpts, max_subplots=len(images), save=False, threaded=False
|
109
|
-
)
|
110
|
-
|
111
|
-
|
112
|
-
def prompt_sql_query(query):
|
113
|
-
"""Plots images with optional labels from a similar data set."""
|
114
|
-
check_requirements("openai>=1.6.1")
|
115
|
-
from openai import OpenAI
|
116
|
-
|
117
|
-
if not SETTINGS["openai_api_key"]:
|
118
|
-
logger.warning("OpenAI API key not found in settings. Please enter your API key below.")
|
119
|
-
openai_api_key = getpass.getpass("OpenAI API key: ")
|
120
|
-
SETTINGS.update({"openai_api_key": openai_api_key})
|
121
|
-
openai = OpenAI(api_key=SETTINGS["openai_api_key"])
|
122
|
-
|
123
|
-
messages = [
|
124
|
-
{
|
125
|
-
"role": "system",
|
126
|
-
"content": """
|
127
|
-
You are a helpful data scientist proficient in SQL. You need to output exactly one SQL query based on
|
128
|
-
the following schema and a user request. You only need to output the format with fixed selection
|
129
|
-
statement that selects everything from "'table'", like `SELECT * from 'table'`
|
130
|
-
|
131
|
-
Schema:
|
132
|
-
im_file: string not null
|
133
|
-
labels: list<item: string> not null
|
134
|
-
child 0, item: string
|
135
|
-
cls: list<item: int64> not null
|
136
|
-
child 0, item: int64
|
137
|
-
bboxes: list<item: list<item: double>> not null
|
138
|
-
child 0, item: list<item: double>
|
139
|
-
child 0, item: double
|
140
|
-
masks: list<item: list<item: list<item: int64>>> not null
|
141
|
-
child 0, item: list<item: list<item: int64>>
|
142
|
-
child 0, item: list<item: int64>
|
143
|
-
child 0, item: int64
|
144
|
-
keypoints: list<item: list<item: list<item: double>>> not null
|
145
|
-
child 0, item: list<item: list<item: double>>
|
146
|
-
child 0, item: list<item: double>
|
147
|
-
child 0, item: double
|
148
|
-
vector: fixed_size_list<item: float>[256] not null
|
149
|
-
child 0, item: float
|
150
|
-
|
151
|
-
Some details about the schema:
|
152
|
-
- the "labels" column contains the string values like 'person' and 'dog' for the respective objects
|
153
|
-
in each image
|
154
|
-
- the "cls" column contains the integer values on these classes that map them the labels
|
155
|
-
|
156
|
-
Example of a correct query:
|
157
|
-
request - Get all data points that contain 2 or more people and at least one dog
|
158
|
-
correct query-
|
159
|
-
SELECT * FROM 'table' WHERE ARRAY_LENGTH(cls) >= 2 AND ARRAY_LENGTH(FILTER(labels, x -> x = 'person')) >= 2 AND ARRAY_LENGTH(FILTER(labels, x -> x = 'dog')) >= 1;
|
160
|
-
""",
|
161
|
-
},
|
162
|
-
{"role": "user", "content": f"{query}"},
|
163
|
-
]
|
164
|
-
|
165
|
-
response = openai.chat.completions.create(model="gpt-3.5-turbo", messages=messages)
|
166
|
-
return response.choices[0].message.content
|