mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-06-23 16:29:25 +08:00
Naming and tooltip adjustments
This commit is contained in:
parent
0d0b008b83
commit
3fe0a695b1
@ -54,10 +54,10 @@ class SAM3DBody_Loader(io.ComfyNode):
|
|||||||
io.Combo.Input(
|
io.Combo.Input(
|
||||||
"model_file",
|
"model_file",
|
||||||
options=folder_paths.get_filename_list("detection"),
|
options=folder_paths.get_filename_list("detection"),
|
||||||
tooltip="SAM 3D Body weights (.safetensors) in the 'detection' folder",
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
outputs=[SAM3DBodyModel.Output("model", display_name="sam3d_body_model")],
|
outputs=[SAM3DBodyModel.Output(display_name="sam3d_body_model")],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -126,40 +126,35 @@ class SAM3DBody_Predict(io.ComfyNode):
|
|||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
return io.Schema(
|
return io.Schema(
|
||||||
node_id="SAM3DBody_Predict",
|
node_id="SAM3DBody_Predict",
|
||||||
display_name="Predict SAM3D Body",
|
display_name="Run SAM3D Body Prediction",
|
||||||
category="image/detection/sam3dbody/",
|
category="image/detection",
|
||||||
inputs=[
|
inputs=[
|
||||||
SAM3DBodyModel.Input("sam3d_body_model"),
|
SAM3DBodyModel.Input("sam3d_body_model"),
|
||||||
io.Image.Input("image"),
|
io.Image.Input("image"),
|
||||||
SAM3TrackData.Input(
|
SAM3TrackData.Input(
|
||||||
"sam3_track_data", optional=True,
|
"track_data", optional=True,
|
||||||
tooltip=("Output of SAM3 Video Track, required for multi-person detection"),
|
tooltip=("Tracking data from SAM3 Video Track, required for multi-person detection"),
|
||||||
),
|
),
|
||||||
io.BoundingBox.Input(
|
io.BoundingBox.Input(
|
||||||
"bboxes", optional=True, force_input=True,
|
"bboxes", optional=True, force_input=True,
|
||||||
tooltip=(
|
tooltip=(
|
||||||
"Per-frame person boxes (e.g. RT-DETR Detect with class_name='person'). "
|
"Per-frame bounding boxes used for better detection. Can be used as an alternative to tracking data. "
|
||||||
"Use for better detection as alternative to SAM3 tracks."
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
io.Boolean.Input(
|
io.Boolean.Input(
|
||||||
"run_hand_refinement", default=True,
|
"run_hand_refinement", default=True,
|
||||||
tooltip="Improves hand pose at the cost of extra inference time and memory use"),
|
tooltip="Improves hand pose at the cost of extra inference time and memory use"),
|
||||||
io.Float.Input(
|
io.Float.Input(
|
||||||
"fov_degrees",
|
"fov",
|
||||||
default=0.0, min=0.0, max=170.0, step=0.5,
|
|
||||||
tooltip=(
|
tooltip=(
|
||||||
"Vertical FOV in degrees. Affects predicted depth (cam_t.z) and "
|
"Vertical FoV in degrees. Affects predicted depth and absolute scale. 0 = fall back to ~53° (16:9)."
|
||||||
"absolute scale. 0 = fall back to ~53° (16:9). Feed MoGeGeometryToFOV "
|
|
||||||
"here to derive it from a MoGe estimate."
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
io.Int.Input(
|
io.Int.Input(
|
||||||
"chunk_size", #TODO: automate?
|
"chunk_size", #TODO: automate?
|
||||||
default=64, min=1, max=512, step=1, advanced=True,
|
default=64, min=1, max=512, step=1, advanced=True,
|
||||||
tooltip=(
|
tooltip=(
|
||||||
"Max person-crops per forward. Higher = throughput + VRAM; "
|
"Max frames to process as a batch. Larger values utilize more VRAM for faster inference."
|
||||||
"per-chunk frame count is chunk_size / persons_per_frame."
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -167,7 +162,7 @@ class SAM3DBody_Predict(io.ComfyNode):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def execute(cls, sam3d_body_model, image, sam3_track_data=None, bboxes=None, run_hand_refinement=True, fov_degrees=0.0, chunk_size=64) -> io.NodeOutput:
|
def execute(cls, sam3d_body_model, image, sam3_track_data=None, bboxes=None, run_hand_refinement=True, fov=0.0, chunk_size=64) -> io.NodeOutput:
|
||||||
comfy.model_management.load_model_gpu(sam3d_body_model)
|
comfy.model_management.load_model_gpu(sam3d_body_model)
|
||||||
inner: SAM3DBody = sam3d_body_model.model
|
inner: SAM3DBody = sam3d_body_model.model
|
||||||
|
|
||||||
@ -187,8 +182,8 @@ class SAM3DBody_Predict(io.ComfyNode):
|
|||||||
per_frame_bboxes = [full_frame_bbox.clone() for _ in range(B)]
|
per_frame_bboxes = [full_frame_bbox.clone() for _ in range(B)]
|
||||||
per_frame_masks = None
|
per_frame_masks = None
|
||||||
inference_type = "full" if run_hand_refinement else "body"
|
inference_type = "full" if run_hand_refinement else "body"
|
||||||
# fov_degrees > 0 sets intrinsics; else None falls back to prepare_batch's diagonal default.
|
# fov > 0 sets intrinsics; else None falls back to prepare_batch's diagonal default.
|
||||||
cam_int = cam_int_from_fov(int(H), int(W), float(fov_degrees))
|
cam_int = cam_int_from_fov(int(H), int(W), float(fov))
|
||||||
|
|
||||||
frames_rgb: List[Optional[torch.Tensor]] = []
|
frames_rgb: List[Optional[torch.Tensor]] = []
|
||||||
for f in range(B):
|
for f in range(B):
|
||||||
@ -259,8 +254,8 @@ class SAM3DBody_FaceExpression(io.ComfyNode):
|
|||||||
display_name="Face Expression to SAM3D Body", #TODO: better name?
|
display_name="Face Expression to SAM3D Body", #TODO: better name?
|
||||||
category="image/detection/sam3dbody/",
|
category="image/detection/sam3dbody/",
|
||||||
inputs=[
|
inputs=[
|
||||||
MHRPoseData.Input("mhr_pose_data"),
|
|
||||||
SAM3DBodyModel.Input("sam3d_body_model"),
|
SAM3DBodyModel.Input("sam3d_body_model"),
|
||||||
|
MHRPoseData.Input("mhr_pose_data"),
|
||||||
io.Image.Input("image"),
|
io.Image.Input("image"),
|
||||||
io.Float.Input(
|
io.Float.Input(
|
||||||
"strength", default=1.0, min=0.0, max=4.0, step=0.05,
|
"strength", default=1.0, min=0.0, max=4.0, step=0.05,
|
||||||
@ -268,17 +263,17 @@ class SAM3DBody_FaceExpression(io.ComfyNode):
|
|||||||
),
|
),
|
||||||
io.Float.Input(
|
io.Float.Input(
|
||||||
"mouth_strength", default=1.0, min=0.0, max=4.0, step=0.05,
|
"mouth_strength", default=1.0, min=0.0, max=4.0, step=0.05,
|
||||||
tooltip="Multiplier on mouth/jaw shapes. MP's jawOpen saturates near 1.0.",
|
tooltip="Multiplier on mouth/jaw shapes. MediaPipe's jawOpen saturates near 1.0.",
|
||||||
advanced=True,
|
advanced=True,
|
||||||
),
|
),
|
||||||
io.Float.Input(
|
io.Float.Input(
|
||||||
"eye_strength", default=2.0, min=0.0, max=4.0, step=0.05,
|
"eye_strength", default=2.0, min=0.0, max=4.0, step=0.05,
|
||||||
tooltip="Multiplier on eye shapes. MP rarely exceeds 0.5; 2-3x often needed.",
|
tooltip="Multiplier on eye shapes. MediaPipe rarely exceeds 0.5; 2-3x often needed.",
|
||||||
advanced=True,
|
advanced=True,
|
||||||
),
|
),
|
||||||
io.Float.Input(
|
io.Float.Input(
|
||||||
"brow_strength", default=2.0, min=0.0, max=4.0, step=0.05,
|
"brow_strength", default=2.0, min=0.0, max=4.0, step=0.05,
|
||||||
tooltip="Multiplier on brow/cheek/sneer shapes. MP outputs ~0.1-0.3; 2-3x.",
|
tooltip="Multiplier on brow/cheek/sneer shapes. MediaPipe outputs ~0.1-0.3; 2-3x.",
|
||||||
advanced=True,
|
advanced=True,
|
||||||
),
|
),
|
||||||
io.Float.Input(
|
io.Float.Input(
|
||||||
@ -451,23 +446,23 @@ class SAM3DBody_Smooth(io.ComfyNode):
|
|||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
return io.Schema(
|
return io.Schema(
|
||||||
node_id="SAM3DBody_Smooth",
|
node_id="SAM3DBody_Smooth",
|
||||||
description="Reduce frame-to-frame jitter via vertex-space temporal averaging",
|
description="Reduce frame-to-frame jitter via temporal smoothing.",
|
||||||
display_name="Smooth SAM3D Body Pose Frames",
|
display_name="Smooth SAM3D Body Pose Data",
|
||||||
category="image/detection/sam3dbody/",
|
category="image/detection/sam3dbody/",
|
||||||
inputs=[
|
inputs=[
|
||||||
MHRPoseData.Input("mhr_pose_data"),
|
MHRPoseData.Input("mhr_pose_data"),
|
||||||
io.Float.Input(
|
io.Float.Input(
|
||||||
"strength",
|
"strength",
|
||||||
default=1.0, min=0.0, max=1.0, step=0.05,
|
default=1.0, min=0.0, max=1.0, step=0.05,
|
||||||
tooltip="Blend raw (0) → smoothed (1).",
|
tooltip="Smoothing strength. 0 = raw, 1 = smoothed.",
|
||||||
),
|
),
|
||||||
io.Combo.Input(
|
io.Combo.Input(
|
||||||
"method",
|
"method",
|
||||||
options=["gaussian", "savgol"],
|
options=["gaussian", "savgol"],
|
||||||
default="gaussian", advanced=True,
|
default="gaussian", advanced=True,
|
||||||
tooltip=(
|
tooltip=(
|
||||||
"'gaussian': symmetric weighted average, best general-purpose smoother. "
|
"gaussian: symmetric weighted average, best general-purpose smoother./n"
|
||||||
"'savgol': sliding polynomial fit, preserves sharp peaks."
|
"savgol: sliding polynomial fit, preserves sharp peaks."
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
io.Int.Input(
|
io.Int.Input(
|
||||||
@ -477,11 +472,11 @@ class SAM3DBody_Smooth(io.ComfyNode):
|
|||||||
),
|
),
|
||||||
io.Float.Input(
|
io.Float.Input(
|
||||||
"rotation_threshold_deg",
|
"rotation_threshold_deg",
|
||||||
default=15.0, min=0.0, max=45.0, step=1.0, advanced=True,
|
default=30.0, min=0.0, max=90.0, step=1.0, advanced=True,
|
||||||
tooltip=(
|
tooltip=(
|
||||||
"Disables smoothing for this root-rotation rate (deg/frame) to preserve fast spins. "
|
"Disables smoothing for this root rotation rate (degree/frame) to preserve fast spins. "
|
||||||
"15° suits most content, low values trigger on ordinary jitter and "
|
"30° suits most content, low values might disable smoothing on ordinary jitter and "
|
||||||
"silently sabotage smoothing. 0 = disable."
|
"silently impacts quality. 0 = disable."
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -870,11 +865,9 @@ class SAM3DBody_Render(io.ComfyNode):
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
io.Float.Input(
|
io.Float.Input(
|
||||||
"camera_fov", default=0.0, min=0.0, max=170.0, step=0.5, advanced=True,
|
"fov", default=0.0, min=0.0, max=170.0, step=0.5, advanced=True,
|
||||||
tooltip=(
|
tooltip=(
|
||||||
"Vertical FOV for the camera_info override. 0 = keep the SAM3D "
|
"Override the vertical FoV of the camera_info. Ignored when camera_info is empty. 0 = keep the FoV of the camera_info."
|
||||||
"predicted camera's FOV (only the viewpoint changes). Any non-zero "
|
|
||||||
"value overrides the lens. Ignored when camera_info is unwired."
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
io.DynamicCombo.Input(
|
io.DynamicCombo.Input(
|
||||||
@ -900,7 +893,7 @@ class SAM3DBody_Render(io.ComfyNode):
|
|||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def execute(cls, mhr_pose_data, background=None, width=0, height=0, camera_info=None, camera_fov=0.0, render_style=None) -> io.NodeOutput:
|
def execute(cls, mhr_pose_data, background=None, width=0, height=0, camera_info=None, fov=0.0, render_style=None) -> io.NodeOutput:
|
||||||
render_style = render_style or {"render_style": "mesh"}
|
render_style = render_style or {"render_style": "mesh"}
|
||||||
mode_key = render_style.get("render_style", "mesh")
|
mode_key = render_style.get("render_style", "mesh")
|
||||||
|
|
||||||
@ -919,7 +912,7 @@ class SAM3DBody_Render(io.ComfyNode):
|
|||||||
px_scale = min(new_W / native_W, new_H / native_H)
|
px_scale = min(new_W / native_W, new_H / native_H)
|
||||||
|
|
||||||
if camera_info is not None:
|
if camera_info is not None:
|
||||||
mhr_pose_data = apply_camera_override(mhr_pose_data, camera_info, H, W, fov_deg=float(camera_fov))
|
mhr_pose_data = apply_camera_override(mhr_pose_data, camera_info, H, W, fov_deg=float(fov))
|
||||||
|
|
||||||
B = len(mhr_pose_data["frames"])
|
B = len(mhr_pose_data["frames"])
|
||||||
if B == 0:
|
if B == 0:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user