Going somewhere with a coffee
This commit is contained in:
1 parent
236dd82871
commit
a10fdbee50
7 files changed
+247
-143
No files matched your search
@@ -1,25 +1,25 @@
|
|||||||
|
import json5 as json
|
||||||
from contextlib import closing, contextmanager
|
from contextlib import closing, contextmanager
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
from dodgeballtracker.metadata import VideoMetadata
|
||||||
|
|
||||||
|
|
||||||
from dodgeballtracker.helper import time_tracker
|
from dodgeballtracker.helper import time_tracker
|
||||||
from dodgeballtracker.logic import (DodgeballTracker,
|
from dodgeballtracker.logic import (DodgeballTracker,
|
||||||
get_court_perspective_transform)
|
get_court_perspective_transform)
|
||||||
from dodgeballtracker.data_dumper import SQLiteDataDumper
|
from dodgeballtracker.data_dumper import SQLiteDataDumper, DataDumper
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import logging
|
import logging
|
||||||
import click
|
import click
|
||||||
import hashlib
|
import hashlib
|
||||||
from typing import ContextManager
|
from typing import ContextManager, Iterator
|
||||||
|
|
||||||
from dodgeballtracker.video_writer import (MP4VVideoWriter,
|
from dodgeballtracker.video_writer import (MP4VVideoWriter,
|
||||||
VideoWriter,
|
VideoWriter,
|
||||||
DetectedObjectBox,
|
DetectedObjectBox,
|
||||||
MP4VVideoWriterWithFrame)
|
MP4VVideoWriterWithFrame)
|
||||||
|
|
||||||
here = Path(__file__).parent
|
|
||||||
input_dir = here / '..' / 'data'
|
|
||||||
output_dir = here / '..' / 'outputs'
|
|
||||||
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
@@ -53,15 +53,29 @@ def get_file_sha256(file_: Path) -> str:
|
|||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def create_data_dumper(input_file: Path, outout_file: Path):
|
def create_data_dumper(input_file: Path,
|
||||||
with closing(sqlite3.connect(outout_file)) as conn:
|
output_file: Path,
|
||||||
|
metadata: VideoMetadata) -> Iterator[DataDumper]:
|
||||||
|
with closing(sqlite3.connect(output_file)) as conn:
|
||||||
conn.execute('PRAGMA foreign_keys = 1')
|
conn.execute('PRAGMA foreign_keys = 1')
|
||||||
dumper = SQLiteDataDumper(conn)
|
dumper = SQLiteDataDumper(conn)
|
||||||
dumper.start(input_file, get_file_sha256(input_file))
|
dumper.start(input_file, get_file_sha256(input_file), metadata)
|
||||||
yield dumper
|
yield dumper
|
||||||
|
|
||||||
|
def deserialized_video_metadata(positional_data: Path | None) -> VideoMetadata | None:
|
||||||
|
if not positional_data:
|
||||||
|
return None
|
||||||
|
with open(positional_data, 'rt') as file_:
|
||||||
|
data = json.load(file_)
|
||||||
|
return VideoMetadata(**data)
|
||||||
|
|
||||||
|
|
||||||
|
def process_logic(input_: Path,
|
||||||
|
output_dir: Path | None,
|
||||||
|
metadata_file: Path | None,
|
||||||
|
display_video: bool):
|
||||||
|
metadata = deserialized_video_metadata(metadata_file)
|
||||||
|
|
||||||
def process_logic(input_: Path, output_dir: Path | None, display_video: bool):
|
|
||||||
output_dir = get_output_dir(input_, output_dir)
|
output_dir = get_output_dir(input_, output_dir)
|
||||||
detected_box_objects = [
|
detected_box_objects = [
|
||||||
DetectedObjectBox.from_viridis(threshold) for threshold in
|
DetectedObjectBox.from_viridis(threshold) for threshold in
|
||||||
@@ -71,7 +85,7 @@ def process_logic(input_: Path, output_dir: Path | None, display_video: bool):
|
|||||||
transformation_matrix = get_court_perspective_transform()
|
transformation_matrix = get_court_perspective_transform()
|
||||||
|
|
||||||
with get_video_writer(display_video, input_, output_dir / 'video.mov') as video_writer:
|
with get_video_writer(display_video, input_, output_dir / 'video.mov') as video_writer:
|
||||||
with create_data_dumper(input_, output_dir / 'data.sqlite') as data_dumper:
|
with create_data_dumper(input_, output_dir / 'data.sqlite', metadata) as data_dumper:
|
||||||
tracker = DodgeballTracker(input_,
|
tracker = DodgeballTracker(input_,
|
||||||
video_writer,
|
video_writer,
|
||||||
data_dumper,
|
data_dumper,
|
||||||
@@ -86,15 +100,25 @@ def process_logic(input_: Path, output_dir: Path | None, display_video: bool):
|
|||||||
def train():
|
def train():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@click.option('--input', '-i', 'input_',
|
@click.option('--input', '-i', 'input_',
|
||||||
type=click.Path(readable=True, path_type=Path))
|
type=click.Path(readable=True, path_type=Path))
|
||||||
@click.option('--output-dir', '-o', type=click.Path(path_type=Path))
|
@click.option('--output-dir', '-o', type=click.Path(path_type=Path))
|
||||||
|
@click.option('--metadata-file', '-f', type=click.Path(path_type=Path, file_okay=True, exists=True))
|
||||||
@click.option('--display-video', '-d', type=bool, is_flag=True, show_default=True, default=False)
|
@click.option('--display-video', '-d', type=bool, is_flag=True, show_default=True, default=False)
|
||||||
def process(input_: Path, output_dir: Path | None, display_video: bool):
|
def process(input_: Path,
|
||||||
process_logic(input_, output_dir, display_video)
|
output_dir: Path | None,
|
||||||
|
metadata_file: Path | None,
|
||||||
|
display_video: bool):
|
||||||
|
process_logic(input_,
|
||||||
|
output_dir,
|
||||||
|
metadata_file,
|
||||||
|
display_video)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
cli()
|
cli()
|
||||||
# process_logic(Path('/home/didier/all-dressed-programming/dodgeball-tracker/data/experiments/rue-honore-beaugrand-ouest-001.MOV'), None, False)
|
# process_logic(Path('/home/didier/all-dressed-programming/dodgeball-tracker/data/experiments/rue-honore-beaugrand-ouest-001.MOV'),
|
||||||
|
# Path('/home/didier/all-dressed-programming/dodgeball-tracker/outputs/benchmark-001'),
|
||||||
|
# False)
|
||||||
@@ -2,6 +2,8 @@ import abc
|
|||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from dodgeballtracker.metadata import VideoMetadata
|
||||||
from dodgeballtracker.typing import TrackedDetectedObject, VideoTimestamp
|
from dodgeballtracker.typing import TrackedDetectedObject, VideoTimestamp
|
||||||
from sqlite3 import Connection
|
from sqlite3 import Connection
|
||||||
|
|
||||||
@@ -61,15 +63,20 @@ class SQLiteDataDumper(DataDumper):
|
|||||||
ymax DOUBLE PRECISION NOT NULL,
|
ymax DOUBLE PRECISION NOT NULL,
|
||||||
score DOUBLE PRECISION NOT NULL,
|
score DOUBLE PRECISION NOT NULL,
|
||||||
category INTEGER NOT NULL,
|
category INTEGER NOT NULL,
|
||||||
|
object_id INTEGER NOT NULL,
|
||||||
video_frame_id INTEGER NOT NULL,
|
video_frame_id INTEGER NOT NULL,
|
||||||
|
|
||||||
|
|
||||||
FOREIGN KEY(video_frame_id) REFERENCES video_frame(id)
|
FOREIGN KEY(video_frame_id) REFERENCES video_frame(id)
|
||||||
);
|
);
|
||||||
''')
|
''')
|
||||||
|
|
||||||
self._conn.commit()
|
self._conn.commit()
|
||||||
|
|
||||||
def start(self, video_path: Path, hexa_hash: str) -> None:
|
def start(self,
|
||||||
|
video_path: Path,
|
||||||
|
hexa_hash: str,
|
||||||
|
metadata: VideoMetadata|None=None) -> None:
|
||||||
self._create_tables()
|
self._create_tables()
|
||||||
|
|
||||||
cur = self._conn.cursor()
|
cur = self._conn.cursor()
|
||||||
@@ -101,9 +108,16 @@ class SQLiteDataDumper(DataDumper):
|
|||||||
RETURNING id
|
RETURNING id
|
||||||
''', (ts, frame_index, self._video_id))
|
''', (ts, frame_index, self._video_id))
|
||||||
frame_id = res.fetchone()[0]
|
frame_id = res.fetchone()[0]
|
||||||
cols = ['xmin', 'ymin', 'xmax', 'ymax', 'score', 'category']
|
cols = ['xmin', 'ymin', 'xmax', 'ymax', 'score', 'category', 'object_id']
|
||||||
cur.executemany('''
|
cur.executemany('''
|
||||||
INSERT INTO tracked_detected_object(xmin, ymin, xmax, ymax, score, category, video_frame_id)
|
INSERT INTO tracked_detected_object(xmin,
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
ymin,
|
||||||
|
xmax,
|
||||||
|
ymax,
|
||||||
|
score,
|
||||||
|
category,
|
||||||
|
object_id,
|
||||||
|
video_frame_id)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
''', (list(x[cols]) + [frame_id] for x in df.iloc))
|
''', (list(x[cols]) + [frame_id] for x in df.iloc))
|
||||||
self._conn.commit()
|
self._conn.commit()
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
class KnownImagePoint(BaseModel):
|
||||||
|
height: float
|
||||||
|
width: float
|
||||||
|
|
||||||
|
|
||||||
|
class BirdViewPoint(BaseModel):
|
||||||
|
x: float
|
||||||
|
y: float
|
||||||
|
|
||||||
|
|
||||||
|
class KnownPoint(BaseModel):
|
||||||
|
image: KnownImagePoint
|
||||||
|
bird_view: BirdViewPoint
|
||||||
|
|
||||||
|
|
||||||
|
class VideoMetadata(BaseModel):
|
||||||
|
knownPoints: list[KnownPoint]
|
||||||
|
|
||||||
@@ -3,6 +3,8 @@ import tempfile
|
|||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from sqlite3 import Connection
|
from sqlite3 import Connection
|
||||||
|
|
||||||
|
from dodgeballtracker.metadata import VideoMetadata
|
||||||
from dodgeballtracker.typing import TrackedDetectedObject
|
from dodgeballtracker.typing import TrackedDetectedObject
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
@@ -27,6 +29,12 @@ def list_tables(conn: Connection) -> set[str]:
|
|||||||
''')
|
''')
|
||||||
return {row[0] for row in res}
|
return {row[0] for row in res}
|
||||||
|
|
||||||
|
def video_metadata() -> VideoMetadata:
|
||||||
|
data = {
|
||||||
|
|
||||||
|
}
|
||||||
|
return VideoMetadata()
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def tmp_dir():
|
def tmp_dir():
|
||||||
with tempfile.TemporaryDirectory() as dir_:
|
with tempfile.TemporaryDirectory() as dir_:
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ def tensor_of(data_type: pa.DataType, cols: list[str]) -> pa.DataFrameSchema:
|
|||||||
return pa.DataFrameSchema({col: pa.Column(data_type) for col in cols})
|
return pa.DataFrameSchema({col: pa.Column(data_type) for col in cols})
|
||||||
|
|
||||||
|
|
||||||
DetectedObject = tensor_of(Float32, ["xmin", "ymin", "xmax", "ymax", "score",
|
DetectedObject = tensor_of(Float32, ["xmin", "ymin", "xmax", "ymax", "score", "category"])
|
||||||
"category"])
|
|
||||||
|
|
||||||
TrackedDetectedObject = tensor_of(Float64,
|
TrackedDetectedObject = tensor_of(Float64,
|
||||||
list(DetectedObject.columns) + ["object_id", "index"])
|
list(DetectedObject.columns) + ["object_id", "index"])
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
*.json
|
|
||||||
*.mp4
|
|
||||||
+163
-122
@@ -1,165 +1,206 @@
|
|||||||
absl-py==2.1.0
|
absl-py==2.1.0
|
||||||
anyio==4.2.0
|
aiodns==3.2.0
|
||||||
appnope==0.1.3
|
aiohappyeyeballs==2.3.6
|
||||||
|
aiohttp==3.10.5
|
||||||
|
aiosignal==1.3.1
|
||||||
|
annotated-types==0.7.0
|
||||||
|
anyio==4.4.0
|
||||||
argon2-cffi==23.1.0
|
argon2-cffi==23.1.0
|
||||||
argon2-cffi-bindings==21.2.0
|
argon2-cffi-bindings==21.2.0
|
||||||
arrow==1.3.0
|
arrow==1.3.0
|
||||||
asttokens==2.4.1
|
asttokens==2.4.1
|
||||||
|
astunparse==1.6.3
|
||||||
async-lru==2.0.4
|
async-lru==2.0.4
|
||||||
|
async-timeout==4.0.3
|
||||||
|
async_generator==1.10
|
||||||
attrs==23.2.0
|
attrs==23.2.0
|
||||||
Babel==2.14.0
|
Babel==2.15.0
|
||||||
beautifulsoup4==4.12.2
|
bcrypt==4.1.3
|
||||||
|
beautifulsoup4==4.12.3
|
||||||
bleach==6.1.0
|
bleach==6.1.0
|
||||||
boxmot==10.0.51
|
boxmot==10.0.81
|
||||||
build==1.0.3
|
Brotli==1.1.0
|
||||||
|
brotlicffi==1.1.0.0
|
||||||
cachetools==5.3.2
|
cachetools==5.3.2
|
||||||
certifi==2023.11.17
|
certifi==2024.7.4
|
||||||
cffi==1.16.0
|
cffi==1.17.1
|
||||||
cfgv==3.4.0
|
chardet==5.2.0
|
||||||
charset-normalizer==3.3.2
|
charset-normalizer==3.3.2
|
||||||
click==8.1.7
|
click==8.1.7
|
||||||
comm==0.2.1
|
comm==0.2.2
|
||||||
contourpy==1.2.0
|
contourpy==1.2.1
|
||||||
|
cryptography==43.0.0
|
||||||
|
curio==1.6
|
||||||
|
curl_cffi==0.7.1
|
||||||
cycler==0.12.1
|
cycler==0.12.1
|
||||||
Cython==3.0.8
|
ddt==1.7.2
|
||||||
debugpy==1.8.0
|
|
||||||
decorator==5.1.1
|
decorator==5.1.1
|
||||||
deep-sort-realtime==1.3.2
|
defusedxml==0.8.0rc2
|
||||||
defusedxml==0.7.1
|
executing==2.1.0
|
||||||
distlib==0.3.8
|
|
||||||
exceptiongroup==1.2.0
|
|
||||||
executing==2.0.1
|
|
||||||
fastjsonschema==2.19.1
|
fastjsonschema==2.19.1
|
||||||
filelock==3.13.1
|
filelock==3.15.1
|
||||||
filterpy==1.4.5
|
filterpy==1.4.5
|
||||||
fonttools==4.47.2
|
fonttools==4.53.1
|
||||||
fqdn==1.5.1
|
fqdn==1.5.1
|
||||||
fsspec==2023.12.2
|
frozenlist==1.4.1
|
||||||
ftfy==6.1.3
|
fsspec==2024.3.0
|
||||||
gdown==4.6.3
|
ftfy==6.2.3
|
||||||
|
future==1.0.0
|
||||||
|
gdown==5.2.0
|
||||||
gitdb==4.0.11
|
gitdb==4.0.11
|
||||||
GitPython==3.1.41
|
GitPython==3.1.43
|
||||||
google-auth==2.26.2
|
google-auth==2.30.0
|
||||||
google-auth-oauthlib==1.2.0
|
google-auth-oauthlib==1.2.1
|
||||||
grpcio==1.60.0
|
grpcio==1.64.1
|
||||||
identify==2.5.33
|
gviz-api==1.10.0
|
||||||
idna==3.6
|
h11==0.14.0
|
||||||
ipykernel==6.28.0
|
html5lib==1.1
|
||||||
ipython==8.20.0
|
httpcore==1.0.5
|
||||||
ipywidgets==8.1.1
|
httpx==0.27.0
|
||||||
|
idna==3.7
|
||||||
|
iniconfig==2.0.0
|
||||||
|
ipykernel==6.29.5
|
||||||
|
ipython==8.27.0
|
||||||
|
ipywidgets==8.1.5
|
||||||
isoduration==20.11.0
|
isoduration==20.11.0
|
||||||
jedi==0.19.1
|
jedi==0.19.1
|
||||||
Jinja2==3.1.3
|
jeepney==0.8.0
|
||||||
joblib==1.3.2
|
Jinja2==3.1.4
|
||||||
|
joblib==1.4.2
|
||||||
json5==0.9.14
|
json5==0.9.14
|
||||||
jsonpointer==2.4
|
jsonpointer==3.0.0
|
||||||
jsonschema==4.20.0
|
jsonschema==4.22.0
|
||||||
jsonschema-specifications==2023.12.1
|
jsonschema-specifications==2023.12.1
|
||||||
jupyter==1.0.0
|
jupyter==1.1.1
|
||||||
jupyter-console==6.6.3
|
jupyter-console==6.6.3
|
||||||
jupyter-events==0.9.0
|
jupyter-events==0.10.0
|
||||||
jupyter-lsp==2.2.1
|
jupyter-lsp==2.2.5
|
||||||
jupyter_client==8.6.0
|
jupyter_client==8.6.2
|
||||||
jupyter_core==5.7.1
|
jupyter_core==5.7.2
|
||||||
jupyter_server==2.12.4
|
jupyter_server==2.14.2
|
||||||
jupyter_server_terminals==0.5.1
|
jupyter_server_terminals==0.5.3
|
||||||
jupyterlab==4.0.10
|
jupyterlab==4.2.5
|
||||||
jupyterlab-widgets==3.0.9
|
|
||||||
jupyterlab_pygments==0.3.0
|
jupyterlab_pygments==0.3.0
|
||||||
jupyterlab_server==2.25.2
|
jupyterlab_server==2.27.3
|
||||||
|
jupyterlab_widgets==3.0.13
|
||||||
kiwisolver==1.4.5
|
kiwisolver==1.4.5
|
||||||
lapx==0.5.5
|
lapx==0.5.11
|
||||||
loguru==0.7.2
|
loguru==0.7.2
|
||||||
Markdown==3.5.2
|
lz4==4.3.3
|
||||||
MarkupSafe==2.1.3
|
Markdown==3.7
|
||||||
matplotlib==3.8.2
|
MarkupSafe==2.1.5
|
||||||
matplotlib-inline==0.1.6
|
matplotlib==3.9.1
|
||||||
|
matplotlib-inline==0.1.7
|
||||||
mistune==3.0.2
|
mistune==3.0.2
|
||||||
mpmath==1.3.0
|
mpmath==1.3.0
|
||||||
nbclient==0.9.0
|
multidict==6.1.0
|
||||||
nbconvert==7.14.1
|
multimethod==1.9.1
|
||||||
nbformat==5.9.2
|
mutagen==1.47.0
|
||||||
nest-asyncio==1.5.8
|
mypy_extensions==1.0.0
|
||||||
networkx==3.2.1
|
nbclient==0.10.0
|
||||||
nodeenv==1.8.0
|
nbconvert==7.16.4
|
||||||
notebook==7.0.6
|
nbformat==5.10.4
|
||||||
notebook_shim==0.2.3
|
nest_asyncio==1.6.0
|
||||||
numpy==1.24.4
|
networkx==3.3
|
||||||
|
notebook==7.2.2
|
||||||
|
notebook_shim==0.2.4
|
||||||
|
numpy==1.26.4
|
||||||
oauthlib==3.2.2
|
oauthlib==3.2.2
|
||||||
opencv-python==4.9.0.80
|
olefile==0.47
|
||||||
overrides==7.4.0
|
opencv @ file:///build/source/modules/python/package/dist/opencv-4.9.0-py3-none-any.whl#sha256=0b1c6093b66ec745df186877df1e6e72241dfe8dda392f023bc361fe1d5411ca
|
||||||
packaging==23.2
|
outcome==1.3.0.post0
|
||||||
pandas==2.1.4
|
overrides==7.7.0
|
||||||
pandocfilters==1.5.0
|
packaging==24.1
|
||||||
parso==0.8.3
|
pandas==2.2.2
|
||||||
|
pandera==0.20.4
|
||||||
|
pandocfilters==1.5.1
|
||||||
|
paramiko==3.5.0
|
||||||
|
parso==0.8.4
|
||||||
pexpect==4.9.0
|
pexpect==4.9.0
|
||||||
pillow==10.2.0
|
pillow==10.4.0
|
||||||
pip-tools==7.3.0
|
platformdirs==4.2.2
|
||||||
platformdirs==4.1.0
|
pluggy==1.5.0
|
||||||
pre-commit==3.6.0
|
prometheus_client==0.21.0
|
||||||
prometheus-client==0.19.0
|
prompt_toolkit==3.0.47
|
||||||
prompt-toolkit==3.0.43
|
protobuf==5.28.2
|
||||||
protobuf==4.23.4
|
psutil==6.0.0
|
||||||
psutil==5.9.7
|
|
||||||
ptyprocess==0.7.0
|
ptyprocess==0.7.0
|
||||||
pure-eval==0.2.2
|
pure_eval==0.2.2
|
||||||
py-cpuinfo==9.0.0
|
py-cpuinfo==9.0.0
|
||||||
pyasn1==0.5.1
|
pyasn1==0.6.0
|
||||||
pyasn1-modules==0.3.0
|
pyasn1_modules==0.4.0
|
||||||
pycparser==2.21
|
pybind11==2.13.5
|
||||||
Pygments==2.17.2
|
pycares==4.4.0
|
||||||
pyparsing==3.1.1
|
pycparser==2.22
|
||||||
pyproject_hooks==1.0.0
|
pycryptodomex==3.20.0
|
||||||
|
pydantic==2.8.2
|
||||||
|
pydantic_core==2.20.1
|
||||||
|
Pygments==2.18.0
|
||||||
|
pyparsing==3.1.2
|
||||||
PySocks==1.7.1
|
PySocks==1.7.1
|
||||||
python-dateutil==2.8.2
|
pyspnego==0.10.2
|
||||||
|
pytest==8.3.2
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
python-json-logger==2.0.7
|
python-json-logger==2.0.7
|
||||||
pytz==2023.3.post1
|
python-socks==2.4.4
|
||||||
PyYAML==6.0.1
|
pytz==2024.2
|
||||||
pyzmq==25.1.2
|
PyYAML==6.0.2
|
||||||
qtconsole==5.5.1
|
pyzmq==26.0.3
|
||||||
QtPy==2.4.1
|
referencing==0.34.0
|
||||||
referencing==0.32.1
|
regex==2024.5.15
|
||||||
regex==2023.12.25
|
requests==2.32.3
|
||||||
requests==2.31.0
|
requests-oauthlib==2.0.0
|
||||||
requests-oauthlib==1.3.1
|
rfc3339_validator==0.1.4
|
||||||
rfc3339-validator==0.1.4
|
rfc3986_validator==0.1.1
|
||||||
rfc3986-validator==0.1.1
|
rpds-py==0.18.1
|
||||||
rpds-py==0.17.1
|
|
||||||
rsa==4.9
|
rsa==4.9
|
||||||
scikit-learn==1.4.0
|
scikit-learn==1.5.0
|
||||||
scipy==1.11.4
|
scipy==1.14.0
|
||||||
seaborn==0.13.1
|
seaborn==0.13.2
|
||||||
|
SecretStorage==3.3.3
|
||||||
Send2Trash==1.8.2
|
Send2Trash==1.8.2
|
||||||
|
setuptools==72.1.0.post0
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
smmap==5.0.1
|
smbprotocol==1.12.0
|
||||||
sniffio==1.3.0
|
smmap==6.0.0
|
||||||
|
sniffio==1.3.1
|
||||||
|
sortedcontainers==2.4.0
|
||||||
soupsieve==2.5
|
soupsieve==2.5
|
||||||
stack-data==0.6.3
|
stack_data==0.6.3
|
||||||
sympy==1.12
|
sympy==1.12.1
|
||||||
tensorboard==2.15.1
|
tensorboard==2.17.0
|
||||||
tensorboard-data-server==0.7.2
|
tensorboard-data-server==0.7.2
|
||||||
terminado==0.18.0
|
tensorboard-plugin-profile==2.11.1
|
||||||
thop==0.1.1.post2209072238
|
tensorboard-plugin-wit==1.7.0
|
||||||
threadpoolctl==3.2.0
|
terminado==0.18.1
|
||||||
tinycss2==1.2.1
|
threadpoolctl==3.4.0
|
||||||
tomli==2.0.1
|
tinycss2==1.3.0
|
||||||
torch==2.1.2
|
toml==0.10.2
|
||||||
torchvision==0.16.2
|
torch==2.5.0
|
||||||
tornado==6.4
|
torchvision==0.20.0a0
|
||||||
tqdm==4.66.1
|
tornado==6.4.1
|
||||||
traitlets==5.14.1
|
tqdm==4.66.4
|
||||||
types-python-dateutil==2.8.19.20240106
|
traitlets==5.14.3
|
||||||
typing_extensions==4.9.0
|
trio==0.25.0
|
||||||
tzdata==2023.4
|
triton==3.1.0
|
||||||
ultralytics==8.1.3
|
typeguard==4.3.0
|
||||||
|
types-python-dateutil==2.9.0.20240316
|
||||||
|
typing_extensions==4.12.2
|
||||||
|
typing_inspect==0.9.0
|
||||||
|
tzdata==2024.1
|
||||||
|
ultralytics==8.3.13
|
||||||
|
ultralytics-thop==2.0.9
|
||||||
uri-template==1.3.0
|
uri-template==1.3.0
|
||||||
urllib3==2.1.0
|
urllib3==2.2.2
|
||||||
virtualenv==20.25.0
|
|
||||||
wcwidth==0.2.13
|
wcwidth==0.2.13
|
||||||
webcolors==1.13
|
webcolors==1.13
|
||||||
webencodings==0.5.1
|
webencodings==0.5.1
|
||||||
websocket-client==1.7.0
|
websocket-client==1.8.0
|
||||||
Werkzeug==3.0.1
|
websockets==12.0
|
||||||
widgetsnbextension==4.0.9
|
Werkzeug==3.0.4
|
||||||
|
wheel==0.43.0
|
||||||
|
widgetsnbextension==4.0.13
|
||||||
|
wrapt==1.16.0
|
||||||
yacs==0.1.8
|
yacs==0.1.8
|
||||||
youtube-dl==2021.12.17
|
yarl==1.9.4
|
||||||
|
yt-dlp==2024.10.22
|
||||||
Reference in new issue
Block a user