Skip to content

Commit b446bad

Browse files
committed
Release 7.5.0
1 parent e39ec60 commit b446bad

File tree

11 files changed

+690
-424
lines changed

11 files changed

+690
-424
lines changed

.github/workflows/build.yml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,29 @@ jobs:
3333
name: TinyTouch-linux-x64
3434
path: dist/TinyTouch-${{ github.ref_name }}-linux-x64.zip
3535

36+
build-linux-legacy:
37+
runs-on: ubuntu-20.04
38+
steps:
39+
- uses: actions/checkout@v4
40+
- uses: actions/setup-python@v5
41+
with:
42+
python-version: "3.11"
43+
- name: Install deps
44+
run: |
45+
python -m pip install --upgrade pip setuptools wheel
46+
pip install -r requirements.txt
47+
- name: Build (PyInstaller)
48+
run: |
49+
TINYTOUCH_APP_NAME=TinyTouch-${{ github.ref_name }}-legacy python -m PyInstaller TinyTouch.spec
50+
- name: Package
51+
run: |
52+
cd dist
53+
zip -r TinyTouch-${{ github.ref_name }}-linux-x64-legacy.zip TinyTouch-${{ github.ref_name }}-legacy
54+
- uses: actions/upload-artifact@v4
55+
with:
56+
name: TinyTouch-linux-x64-legacy
57+
path: dist/TinyTouch-${{ github.ref_name }}-linux-x64-legacy.zip
58+
3659
build-windows:
3760
runs-on: windows-latest
3861
steps:
@@ -58,7 +81,7 @@ jobs:
5881

5982
release:
6083
runs-on: ubuntu-latest
61-
needs: [build-linux, build-windows]
84+
needs: [build-linux, build-linux-legacy, build-windows]
6285
if: startsWith(github.ref, 'refs/tags/')
6386
steps:
6487
- uses: actions/download-artifact@v4
@@ -70,4 +93,5 @@ jobs:
7093
name: TinyTouch ${{ github.ref_name }}
7194
files: |
7295
dist/TinyTouch-linux-x64/TinyTouch-${{ github.ref_name }}-linux-x64.zip
96+
dist/TinyTouch-linux-x64-legacy/TinyTouch-${{ github.ref_name }}-linux-x64-legacy.zip
7397
dist/TinyTouch-windows-x64/TinyTouch-${{ github.ref_name }}-windows-x64.zip
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"frame": 229, "total_frames": 323}
1+
{"frame": 303, "total_frames": 323}

Labeled_data/cat3/export/cat3_export.csv

Lines changed: 325 additions & 325 deletions
Large diffs are not rendered by default.
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
{
2-
"Program Version": "7.3.0 (Linux)",
2+
"Program Version": "7.4.0 (Linux)",
33
"Video Name": "cat3",
44
"Labeling Mode": "Normal",
55
"Frame Rate": 25.0,
6-
"Zones Covered With Clothes": null,
6+
"Zones Covered With Clothes": [
7+
"BOX2",
8+
"BOX1",
9+
"BOX3",
10+
"BOX4"
11+
],
712
"Param Labels": {
8-
"Parameter_1": "P1",
13+
"Parameter_1": "Looking1",
914
"Parameter_2": "P2",
1015
"Parameter_3": "P3"
1116
},
1217
"Limb Param Labels": {
13-
"XX_Parameter_1": "Looking",
18+
"XX_Parameter_1": "LP1",
1419
"XX_Parameter_2": "LP2",
15-
"XX_Parameter_3": "LP34"
20+
"XX_Parameter_3": "LP3"
1621
}
1722
}

config.json

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
{
2-
"diagram_scale": 1.5,
3-
"dot_size": 20.0,
2+
"diagram_scale": 1.0,
3+
"dot_size": 10.0,
44
"new_template": false,
55
"minimal_touch_length": 280,
6-
"parameter1": "P1",
6+
"parameter1": "Looking1",
77
"parameter2": "P2",
88
"parameter3": "P3",
9-
"limb_parameter1": "Looking",
9+
"limb_parameter1": "LP1",
1010
"limb_parameter2": "LP2",
11-
"limb_parameter3": "LP34",
12-
"max_display_width": 1080,
13-
"max_display_height": 920,
11+
"limb_parameter3": "LP3",
12+
"video_downscale": 1.0,
1413
"perf_enabled": false,
1514
"perf_log_every_s": 2.0,
1615
"perf_log_top_n": 6

src/cloth_app.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class ClothApp:
1111
def __init__(
1212
self,
1313
master,
14+
on_save_callback,
1415
on_close_callback,
1516
initial_points=None,
1617
diagram_scale=DEFAULT_CLOTH_DIAGRAM_SCALE,
@@ -19,12 +20,25 @@ def __init__(
1920
# Vytvoření nového okna pomocí Toplevel
2021
self.top_level = tk.Toplevel(master)
2122
self.top_level.title("Clothes App")
23+
self.on_save_callback = on_save_callback
2224
self.on_close_callback = on_close_callback
2325
self.diagram_scale = float(diagram_scale)
2426
self.dot_radius = int(dot_radius)
2527

28+
self.controls = tk.Frame(self.top_level, bg='lightgrey')
29+
self.controls.grid(row=0, column=0, sticky="ew", padx=10, pady=(10, 0))
30+
self.controls.columnconfigure(0, weight=1)
31+
32+
save_btn = tk.Button(self.controls, text="Save", command=self.on_save)
33+
save_btn.pack(side="left", padx=5)
34+
35+
save_close_btn = tk.Button(self.controls, text="Save & Close", command=self.on_close)
36+
save_close_btn.pack(side="left", padx=5)
37+
2638
self.f = tk.Frame(self.top_level, bg='lightgrey')
2739
self.f.grid(row=1, column=0, sticky="nsew")
40+
self.top_level.columnconfigure(0, weight=1)
41+
self.top_level.rowconfigure(1, weight=1)
2842

2943
self.dots = {}
3044
self.img = Image.open(resource_path("icons/diagram.png"))
@@ -45,13 +59,20 @@ def __init__(
4559
for x, y in initial_points:
4660
self._create_dot(x, y)
4761

62+
self.top_level.update_idletasks()
63+
controls_h = self.controls.winfo_reqheight()
4864
win_w = self.img.width + 20
49-
win_h = self.img.height + 20
65+
win_h = self.img.height + 20 + controls_h + 10
5066
self.top_level.geometry(f"{win_w}x{win_h}")
5167

68+
def on_save(self):
69+
if self.on_save_callback:
70+
self.on_save_callback(self.dots, self.diagram_scale)
71+
5272
def on_close(self):
5373
# Callback with dots data on close
54-
self.on_close_callback(self.dots, self.diagram_scale)
74+
if self.on_close_callback:
75+
self.on_close_callback(self.dots, self.diagram_scale)
5576
self.top_level.destroy()
5677

5778
def _create_dot(self, x, y):

src/config_utils.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,20 @@ def load_display_limits():
8484
return max_w, max_h
8585

8686

87+
def load_video_downscale():
88+
config_path = _ensure_config_file()
89+
with open(config_path, 'r') as file:
90+
config = json.load(file)
91+
raw = config.get('video_downscale', 1.0)
92+
try:
93+
scale = float(raw)
94+
except Exception:
95+
scale = 1.0
96+
if scale <= 0:
97+
scale = 1.0
98+
return scale
99+
100+
87101
def load_parameter_names_into(video_obj, par_buttons, limb_par_buttons):
88102
"""
89103
Sets names onto the video object and updates the buttons' labels.

src/data_utils.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ def write_export_metadata(meta_path: str,
4242
frame_rate,
4343
clothes_list,
4444
param_labels: dict | None = None,
45-
limb_param_labels: dict | None = None) -> None:
45+
limb_param_labels: dict | None = None,
46+
labeling_time_seconds: float | None = None) -> None:
4647
"""
4748
Writes a JSON sidecar with all non-tabular export metadata that used to be
4849
stuffed into the first 5 lines of *_export.csv.
@@ -56,6 +57,8 @@ def write_export_metadata(meta_path: str,
5657
"Param Labels": param_labels or {},
5758
"Limb Param Labels": limb_param_labels or {},
5859
}
60+
if labeling_time_seconds is not None:
61+
meta["Total Labeling Time (hours)"] = round(float(labeling_time_seconds) / 3600.0, 4)
5962
os.makedirs(os.path.dirname(meta_path), exist_ok=True)
6063
with open(meta_path, "w", encoding="utf-8") as f:
6164
json.dump(meta, f, indent=2, ensure_ascii=False)
@@ -386,7 +389,6 @@ def _xy_str(lst):
386389
row[f"{limb}_X"] = _xy_str(rec.get("X", []))
387390
row[f"{limb}_Y"] = _xy_str(rec.get("Y", []))
388391
row[f"{limb}_Onset"] = rec.get("Onset", "")
389-
row[f"{limb}_Look"] = rec.get("Look", "")
390392
row[f"{limb}_Zones"] = json.dumps(rec.get("Zones", []) or [])
391393

392394
# Global params (canonical keys → fixed columns)
@@ -409,7 +411,7 @@ def _xy_str(lst):
409411
# Exact legacy column order
410412
cols = ["Frame", "Time_ms"]
411413
for limb in ["LH", "LL", "RH", "RL"]:
412-
cols += [f"{limb}_X", f"{limb}_Y", f"{limb}_Onset", f"{limb}_Look", f"{limb}_Zones"]
414+
cols += [f"{limb}_X", f"{limb}_Y", f"{limb}_Onset", f"{limb}_Zones"]
413415
cols += ["Parameter_1", "Parameter_2", "Parameter_3"]
414416
for limb in ["LH", "LL", "RH", "RL"]:
415417
cols += [f"{limb}_Parameter_1", f"{limb}_Parameter_2", f"{limb}_Parameter_3"]
@@ -630,10 +632,8 @@ def merge_and_flip_export(
630632
if col not in merged_df.columns:
631633
merged_df[col] = None
632634

633-
# normalize look columns
634-
for limb in ['LH', 'LL', 'RH', 'RL']:
635-
merged_df = merged_df.drop([c for c in merged_df.columns if c == f'{limb}_Look_x'], axis=1)
636-
merged_df = merged_df.rename(columns={f'{limb}_Look_y': f'{limb}_Look_x'})
635+
# Drop legacy Look columns (no longer used in exports).
636+
merged_df = merged_df.drop(columns=[c for c in merged_df.columns if "_Look" in c], errors="ignore")
637637

638638
merged_df = merged_df.drop_duplicates(subset=['Frame'])
639639
merged_df = merged_df.drop([c for c in merged_df.columns if c.endswith('_y')], axis=1)

0 commit comments

Comments
 (0)