Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
12dd3ee
feat(scail): add scail2 condition embeds node
rookiestar28 Jun 19, 2026
535b593
feat(scail): route scail2 embeds through sampler
rookiestar28 Jun 19, 2026
a53c24a
feat(scail): detect scail2 mask embeddings
rookiestar28 Jun 19, 2026
dc5954e
feat(scail): consume scail2 conditioning in model
rookiestar28 Jun 19, 2026
66355d6
feat(scail): support scail2 context windows
rookiestar28 Jun 19, 2026
a619c67
fix(scail2): pad history channels before patch embedding
rookiestar28 Jun 19, 2026
562a64d
fix(scail2): pad pose latents for pose embedding
rookiestar28 Jun 20, 2026
d1b8d89
fix(scail2): apply replacement reference preprocessing
rookiestar28 Jun 20, 2026
de81d8f
fix(scail2): route clip context to sampler
rookiestar28 Jun 20, 2026
a801ff9
feat(scail2): support SCAIL-Pose2 workflows
rookiestar28 Jun 21, 2026
63af460
fix(scail2): preserve replacement noise mask polarity
rookiestar28 Jun 21, 2026
a635333
fix(scail2): validate context frame maps
rookiestar28 Jun 21, 2026
6c908d6
docs(workflows): update scail2 dual mode example
rookiestar28 Jun 21, 2026
f3f2354
feat(scail2): add native condition strength controls
rookiestar28 Jun 21, 2026
e8759c3
fix(scail2): mask replacement samples initialization
rookiestar28 Jun 21, 2026
2b7fb84
fix(scail2): sanitize replacement condition video
rookiestar28 Jun 22, 2026
79b71f8
docs(workflows): update scail2 workflow example
rookiestar28 Jun 22, 2026
28a8068
fix(scail2): preserve replacement condition structure
rookiestar28 Jun 22, 2026
bcac1c0
fix(scail2): use conservative replacement latent masks
rookiestar28 Jun 22, 2026
7568975
fix(scail2): preserve neutral replacement motion structure
rookiestar28 Jun 22, 2026
fa6c26d
fix(scail2): restore official replacement pose latents
rookiestar28 Jun 22, 2026
ce3b266
fix(scail2): report replacement sample sources
rookiestar28 Jun 22, 2026
fc12726
fix(scail2): grow replacement masks temporally
rookiestar28 Jun 22, 2026
b09a2fb
fix(scail2): align replacement sample windows
rookiestar28 Jun 22, 2026
d880920
docs(scail2): update replacement workflow example
rookiestar28 Jun 22, 2026
62258aa
fix(nlf): preserve multi-person bbox output
rookiestar28 Jun 24, 2026
ad5f327
docs: update replacement workflow example
rookiestar28 Jun 26, 2026
efa4af1
chore: modyfied
rookiestar28 Jun 26, 2026
b568ce0
feat(scail): centralize samples disable contract
rookiestar28 Jun 26, 2026
1913a32
fix(scail): use centralized encode samples contract
rookiestar28 Jun 26, 2026
21c83c0
fix(scail): centralize disabled samples handling
rookiestar28 Jun 26, 2026
ef95cfa
docs(scail): document dual-mode samples behavior
rookiestar28 Jun 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ logs/
.idea
tools/
.vscode/
.venv/
.sessions/
convert_*
*.pt
*.pth
*.pth
.pla*/
ref*/
38 changes: 38 additions & 0 deletions MTV/nlf_bbox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""NLF bbox formatting helpers."""

from __future__ import annotations


def format_nlf_detected_boxes(all_boxes):
"""Format detector xyxy rows for the public BBOX output."""

formatted_boxes = []
for box in all_boxes:
if hasattr(box, "detach"):
box = box.detach()
if hasattr(box, "cpu"):
box = box.cpu()
if hasattr(box, "numel") and box.numel() == 0:
formatted_boxes.append([0.0, 0.0, 0.0, 0.0])
continue
rows = box.tolist() if hasattr(box, "tolist") else box
if not rows:
formatted_boxes.append([0.0, 0.0, 0.0, 0.0])
continue
if isinstance(rows[0], (bool, int, float)):
rows = [rows]
candidates = []
for row in rows:
if len(row) < 4:
continue
x_min, y_min, x_max, y_max = (float(row[index]) for index in range(4))
if x_max <= x_min or y_max <= y_min:
continue
candidates.append([x_min, y_min, x_max, y_max])
if not candidates:
formatted_boxes.append([0.0, 0.0, 0.0, 0.0])
elif len(candidates) == 1:
formatted_boxes.append(candidates[0])
else:
formatted_boxes.append(candidates)
return formatted_boxes
15 changes: 4 additions & 11 deletions MTV/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
folder_paths.add_model_folder_path("nlf", os.path.join(folder_paths.models_dir, "nlf"))

from .motion4d import SMPL_VQVAE, VectorQuantizer, Encoder, Decoder
from .nlf_bbox import format_nlf_detected_boxes

def check_jit_script_function():
if torch.jit.script.__name__ != "script":
Expand Down Expand Up @@ -276,17 +277,9 @@ def predict(self, model, images, per_batch=-1):
'joints3d_nonparam': [all_joints3d_nonparam],
}

# Convert bboxes to list format: [x_min, y_min, x_max, y_max] for each detection
# Each box tensor is shape (1, 5) with [x_min, y_min, x_max, y_max, confidence]
formatted_boxes = []
for box in all_boxes:
# Handle empty detections (no person detected in frame)
if box.numel() == 0 or box.shape[0] == 0:
formatted_boxes.append([0.0, 0.0, 0.0, 0.0])
else:
# Extract first 4 values (x_min, y_min, x_max, y_max), drop confidence
bbox_values = box[0, :4].cpu().tolist()
formatted_boxes.append(bbox_values)
# Keep single-person frames backward compatible, but preserve all
# per-frame people for downstream multi-identity geometry matching.
formatted_boxes = format_nlf_detected_boxes(all_boxes)

return (pose_results, formatted_boxes)

Expand Down
Loading