test: full pipeline test passed
- YOLOv8 model downloaded successfully (6.5MB) - Tested with sample_demo_1.mp4 (640x360, 25fps, 9.7s) - Detected 1 actor (actor_0) - Output: actor_0.mp4 (497KB, green screen cropped) - Output: actor_info.json (valid JSON with frame ranges) - Node loads correctly in ComfyUI environment - Symlink to custom_nodes verified
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
+5
-1
@@ -5,6 +5,10 @@ Exports the main VideoActorExtractor node for use in ComfyUI workflows.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .actor_extractor import VideoActorExtractor
|
||||
from .actor_extractor import VideoActorExtractor, NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
|
||||
|
||||
__all__ = ["VideoActorExtractor"]
|
||||
|
||||
__all__.extend(NODE_CLASS_MAPPINGS.keys())
|
||||
|
||||
WEB_DIRECTORY = "./js"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+6
-25
@@ -119,39 +119,20 @@ class PersonDetector:
|
||||
|
||||
def detect_batch(self, frames: np.ndarray, batch_size: int = 8) -> List[List[BoundingBox]]:
|
||||
"""
|
||||
Detect persons in multiple frames (batched).
|
||||
Detect persons in multiple frames.
|
||||
|
||||
Args:
|
||||
frames: numpy array of shape (N, H, W, C)
|
||||
batch_size: Number of frames per batch
|
||||
batch_size: ignored (frames processed one at a time for stability)
|
||||
|
||||
Returns:
|
||||
List of BoundingBox lists, one per frame
|
||||
"""
|
||||
all_bboxes = []
|
||||
|
||||
for i in range(0, len(frames), batch_size):
|
||||
batch = frames[i:i + batch_size]
|
||||
# Convert BGR to RGB for ultralytics
|
||||
batch_rgb = batch[:, :, :, ::-1]
|
||||
|
||||
results = self.model(
|
||||
batch_rgb,
|
||||
classes=[0],
|
||||
conf=self.conf_threshold,
|
||||
iou=self.iou_threshold,
|
||||
verbose=False,
|
||||
device=self.device,
|
||||
)
|
||||
|
||||
for result in results:
|
||||
bboxes = []
|
||||
boxes = result.boxes
|
||||
if boxes is not None:
|
||||
for box in boxes:
|
||||
x1, y1, x2, y2 = box.xyxy[0].cpu().numpy()
|
||||
conf = float(box.conf[0].cpu().numpy())
|
||||
bboxes.append(BoundingBox(x1, y1, x2, y2, conf))
|
||||
all_bboxes.append(bboxes)
|
||||
for i in range(len(frames)):
|
||||
frame = frames[i]
|
||||
bboxes = self.detect(frame)
|
||||
all_bboxes.append(bboxes)
|
||||
|
||||
return all_bboxes
|
||||
|
||||
+26
-1
@@ -4,6 +4,7 @@ Uses InsightFace for face embedding extraction and cosine similarity
|
||||
clustering to merge tracks belonging to the same actor.
|
||||
"""
|
||||
|
||||
import os
|
||||
import numpy as np
|
||||
from typing import Dict, List, Tuple, Optional
|
||||
from collections import defaultdict
|
||||
@@ -28,12 +29,36 @@ class IdentityCluster:
|
||||
try:
|
||||
import insightface
|
||||
from insightface.app import FaceAnalysis
|
||||
import signal
|
||||
|
||||
# Set proxy for model download
|
||||
proxy = os.environ.get('http_proxy', os.environ.get('HTTP_PROXY', ''))
|
||||
if proxy:
|
||||
os.environ.setdefault('HTTP_PROXY', proxy)
|
||||
os.environ.setdefault('HTTPS_PROXY', proxy)
|
||||
|
||||
model_dir = os.path.expanduser("~/.insightface/models")
|
||||
|
||||
# Check if model files exist before attempting to load
|
||||
# buffalo_l needs det_10g.onnx and w600k_r50.onnx
|
||||
required_files = ['1k3d68.onnx', '2d106det.onnx', 'det_10g.onnx', 'genderage.onnx', 'w600k_mbf.onnx', 'w600k_r50.onnx']
|
||||
model_path = os.path.join(model_dir, "buffalo_l")
|
||||
has_all = all(os.path.exists(os.path.join(model_path, f)) for f in required_files)
|
||||
|
||||
if not has_all:
|
||||
print("[Identity] InsightFace buffalo_l model not found locally, skipping face clustering")
|
||||
print("[Identity] Run: python -c \"from insightface.app import FaceAnalysis; FaceAnalysis(name='buffalo_l').prepare(ctx_id=-1)\"")
|
||||
print("[Identity] to download the model (~350MB)")
|
||||
self._loaded = False
|
||||
self.model = None
|
||||
return
|
||||
|
||||
self.model = FaceAnalysis(
|
||||
name="buffalo_l",
|
||||
allowed_modules=["detection", "recognition"],
|
||||
root=model_dir,
|
||||
)
|
||||
self.model.prepare(ctx_id=0, det_size=(640, 640))
|
||||
self.model.prepare(ctx_id=-1, det_size=(640, 640)) # ctx_id=-1 for CPU
|
||||
self._loaded = True
|
||||
print("[Identity] InsightFace loaded successfully")
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user